OSDN Git Service

mesa: Remember client active texture in _mesa_meta_draw_tex.
[android-x86/external-mesa.git] / src / mesa / drivers / common / meta.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.6
4  *
5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * Meta operations.  Some GL operations can be expressed in terms of
27  * other GL operations.  For example, glBlitFramebuffer() can be done
28  * with texture mapping and glClear() can be done with polygon rendering.
29  *
30  * \author Brian Paul
31  */
32
33
34 #include "main/glheader.h"
35 #include "main/mtypes.h"
36 #include "main/imports.h"
37 #include "main/arrayobj.h"
38 #include "main/blend.h"
39 #include "main/bufferobj.h"
40 #include "main/buffers.h"
41 #include "main/depth.h"
42 #include "main/enable.h"
43 #include "main/fbobject.h"
44 #include "main/image.h"
45 #include "main/macros.h"
46 #include "main/matrix.h"
47 #include "main/mipmap.h"
48 #include "main/polygon.h"
49 #include "main/readpix.h"
50 #include "main/scissor.h"
51 #include "main/shaders.h"
52 #include "main/stencil.h"
53 #include "main/texobj.h"
54 #include "main/texenv.h"
55 #include "main/teximage.h"
56 #include "main/texparam.h"
57 #include "main/texstate.h"
58 #include "main/varray.h"
59 #include "main/viewport.h"
60 #include "shader/program.h"
61 #include "shader/arbprogram.h"
62 #include "swrast/swrast.h"
63 #include "drivers/common/meta.h"
64
65
66 /** Return offset in bytes of the field within a vertex struct */
67 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
68
69
70 /**
71  * State which we may save/restore across meta ops.
72  * XXX this may be incomplete...
73  */
74 struct save_state
75 {
76    GLbitfield SavedState;  /**< bitmask of META_* flags */
77
78    /** META_ALPHA_TEST */
79    GLboolean AlphaEnabled;
80
81    /** META_BLEND */
82    GLboolean BlendEnabled;
83    GLboolean ColorLogicOpEnabled;
84
85    /** META_COLOR_MASK */
86    GLubyte ColorMask[4];
87
88    /** META_DEPTH_TEST */
89    struct gl_depthbuffer_attrib Depth;
90
91    /** META_FOG */
92    GLboolean Fog;
93
94    /** META_PIXEL_STORE */
95    struct gl_pixelstore_attrib Pack, Unpack;
96
97    /** META_RASTERIZATION */
98    GLenum FrontPolygonMode, BackPolygonMode;
99    GLboolean PolygonOffset;
100    GLboolean PolygonSmooth;
101    GLboolean PolygonStipple;
102    GLboolean PolygonCull;
103
104    /** META_SCISSOR */
105    struct gl_scissor_attrib Scissor;
106
107    /** META_SHADER */
108    GLboolean VertexProgramEnabled;
109    struct gl_vertex_program *VertexProgram;
110    GLboolean FragmentProgramEnabled;
111    struct gl_fragment_program *FragmentProgram;
112    GLuint Shader;
113
114    /** META_STENCIL_TEST */
115    struct gl_stencil_attrib Stencil;
116
117    /** META_TRANSFORM */
118    GLenum MatrixMode;
119    GLfloat ModelviewMatrix[16];
120    GLfloat ProjectionMatrix[16];
121    GLfloat TextureMatrix[16];
122    GLbitfield ClipPlanesEnabled;
123
124    /** META_TEXTURE */
125    GLuint ActiveUnit;
126    GLuint ClientActiveUnit;
127    /** for unit[0] only */
128    struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
129    /** mask of TEXTURE_2D_BIT, etc */
130    GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
131    GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
132    GLuint EnvMode;  /* unit[0] only */
133
134    /** META_VERTEX */
135    struct gl_array_object *ArrayObj;
136    struct gl_buffer_object *ArrayBufferObj;
137
138    /** META_VIEWPORT */
139    GLint ViewportX, ViewportY, ViewportW, ViewportH;
140    GLclampd DepthNear, DepthFar;
141
142    /** Miscellaneous (always disabled) */
143    GLboolean Lighting;
144 };
145
146
147 /**
148  * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
149  * This is currently shared by all the meta ops.  But we could create a
150  * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
151  */
152 struct temp_texture
153 {
154    GLuint TexObj;
155    GLenum Target;         /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
156    GLsizei MinSize;       /**< Min texture size to allocate */
157    GLsizei MaxSize;       /**< Max possible texture size */
158    GLboolean NPOT;        /**< Non-power of two size OK? */
159    GLsizei Width, Height; /**< Current texture size */
160    GLenum IntFormat;
161    GLfloat Sright, Ttop;  /**< right, top texcoords */
162 };
163
164
165 /**
166  * State for glBlitFramebufer()
167  */
168 struct blit_state
169 {
170    GLuint ArrayObj;
171    GLuint VBO;
172    GLuint DepthFP;
173 };
174
175
176 /**
177  * State for glClear()
178  */
179 struct clear_state
180 {
181    GLuint ArrayObj;
182    GLuint VBO;
183 };
184
185
186 /**
187  * State for glCopyPixels()
188  */
189 struct copypix_state
190 {
191    GLuint ArrayObj;
192    GLuint VBO;
193 };
194
195
196 /**
197  * State for glDrawPixels()
198  */
199 struct drawpix_state
200 {
201    GLuint ArrayObj;
202    GLuint VBO;
203
204    GLuint StencilFP;  /**< Fragment program for drawing stencil images */
205    GLuint DepthFP;  /**< Fragment program for drawing depth images */
206 };
207
208
209 /**
210  * State for glBitmap()
211  */
212 struct bitmap_state
213 {
214    GLuint ArrayObj;
215    GLuint VBO;
216    struct temp_texture Tex;  /**< separate texture from other meta ops */
217 };
218
219
220 /**
221  * State for _mesa_meta_generate_mipmap()
222  */
223 struct gen_mipmap_state
224 {
225    GLuint ArrayObj;
226    GLuint VBO;
227    GLuint FBO;
228 };
229
230
231 /**
232  * State for glDrawTex()
233  */
234 struct drawtex_state
235 {
236    GLuint ArrayObj;
237    GLuint VBO;
238 };
239
240
241 /**
242  * All per-context meta state.
243  */
244 struct gl_meta_state
245 {
246    struct save_state Save;    /**< state saved during meta-ops */
247
248    struct temp_texture TempTex;
249
250    struct blit_state Blit;    /**< For _mesa_meta_blit_framebuffer() */
251    struct clear_state Clear;  /**< For _mesa_meta_clear() */
252    struct copypix_state CopyPix;  /**< For _mesa_meta_copy_pixels() */
253    struct drawpix_state DrawPix;  /**< For _mesa_meta_draw_pixels() */
254    struct bitmap_state Bitmap;    /**< For _mesa_meta_bitmap() */
255    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_generate_mipmap() */
256
257    struct drawtex_state DrawTex;  /**< For _mesa_meta_draw_tex() */
258 };
259
260
261 /**
262  * Initialize meta-ops for a context.
263  * To be called once during context creation.
264  */
265 void
266 _mesa_meta_init(GLcontext *ctx)
267 {
268    ASSERT(!ctx->Meta);
269
270    ctx->Meta = CALLOC_STRUCT(gl_meta_state);
271 }
272
273
274 /**
275  * Free context meta-op state.
276  * To be called once during context destruction.
277  */
278 void
279 _mesa_meta_free(GLcontext *ctx)
280 {
281    struct gl_meta_state *meta = ctx->Meta;
282
283    if (_mesa_get_current_context()) {
284       /* if there's no current context, these textures, buffers, etc should
285        * still get freed by _mesa_free_context_data().
286        */
287
288       /* the temporary texture */
289       _mesa_DeleteTextures(1, &meta->TempTex.TexObj);
290
291       /* glBlitFramebuffer */
292       _mesa_DeleteBuffersARB(1, & meta->Blit.VBO);
293       _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj);
294       _mesa_DeletePrograms(1, &meta->Blit.DepthFP);
295
296       /* glClear */
297       _mesa_DeleteBuffersARB(1, & meta->Clear.VBO);
298       _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj);
299
300       /* glCopyPixels */
301       _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO);
302       _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
303
304       /* glDrawPixels */
305       _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO);
306       _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
307       _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP);
308       _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);
309
310       /* glBitmap */
311       _mesa_DeleteBuffersARB(1, & meta->Bitmap.VBO);
312       _mesa_DeleteVertexArraysAPPLE(1, &meta->Bitmap.ArrayObj);
313       _mesa_DeleteTextures(1, &meta->Bitmap.Tex.TexObj);
314
315       /* glDrawTex */
316       _mesa_DeleteBuffersARB(1, & meta->DrawTex.VBO);
317       _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawTex.ArrayObj);
318
319    }
320
321    _mesa_free(ctx->Meta);
322    ctx->Meta = NULL;
323 }
324
325
326 /**
327  * Enter meta state.  This is like a light-weight version of glPushAttrib
328  * but it also resets most GL state back to default values.
329  *
330  * \param state  bitmask of META_* flags indicating which attribute groups
331  *               to save and reset to their defaults
332  */
333 static void
334 _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
335 {
336    struct save_state *save = &ctx->Meta->Save;
337
338    save->SavedState = state;
339
340    if (state & META_ALPHA_TEST) {
341       save->AlphaEnabled = ctx->Color.AlphaEnabled;
342       if (ctx->Color.AlphaEnabled)
343          _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
344    }
345
346    if (state & META_BLEND) {
347       save->BlendEnabled = ctx->Color.BlendEnabled;
348       if (ctx->Color.BlendEnabled)
349          _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
350       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
351       if (ctx->Color.ColorLogicOpEnabled)
352          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
353    }
354
355    if (state & META_COLOR_MASK) {
356       COPY_4V(save->ColorMask, ctx->Color.ColorMask);
357       if (!ctx->Color.ColorMask[0] ||
358           !ctx->Color.ColorMask[1] ||
359           !ctx->Color.ColorMask[2] ||
360           !ctx->Color.ColorMask[3])
361          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
362    }
363
364    if (state & META_DEPTH_TEST) {
365       save->Depth = ctx->Depth; /* struct copy */
366       if (ctx->Depth.Test)
367          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
368    }
369
370    if (state & META_FOG) {
371       save->Fog = ctx->Fog.Enabled;
372       if (ctx->Fog.Enabled)
373          _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
374    }
375
376    if (state & META_PIXEL_STORE) {
377       save->Pack = ctx->Pack;
378       save->Unpack = ctx->Unpack;
379       ctx->Pack = ctx->DefaultPacking;
380       ctx->Unpack = ctx->DefaultPacking;
381    }
382
383    if (state & META_RASTERIZATION) {
384       save->FrontPolygonMode = ctx->Polygon.FrontMode;
385       save->BackPolygonMode = ctx->Polygon.BackMode;
386       save->PolygonOffset = ctx->Polygon.OffsetFill;
387       save->PolygonSmooth = ctx->Polygon.SmoothFlag;
388       save->PolygonStipple = ctx->Polygon.StippleFlag;
389       save->PolygonCull = ctx->Polygon.CullFlag;
390       _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
391       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
392       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
393       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
394       _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
395    }
396
397    if (state & META_SCISSOR) {
398       save->Scissor = ctx->Scissor; /* struct copy */
399    }
400
401    if (state & META_SHADER) {
402       if (ctx->Extensions.ARB_vertex_program) {
403          save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
404          save->VertexProgram = ctx->VertexProgram.Current;
405          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
406       }
407
408       if (ctx->Extensions.ARB_fragment_program) {
409          save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
410          save->FragmentProgram = ctx->FragmentProgram.Current;
411          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
412       }
413
414       if (ctx->Extensions.ARB_shader_objects) {
415          save->Shader = ctx->Shader.CurrentProgram ?
416             ctx->Shader.CurrentProgram->Name : 0;
417          _mesa_UseProgramObjectARB(0);
418       }
419    }
420
421    if (state & META_STENCIL_TEST) {
422       save->Stencil = ctx->Stencil; /* struct copy */
423       if (ctx->Stencil.Enabled)
424          _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
425       /* NOTE: other stencil state not reset */
426    }
427
428    if (state & META_TEXTURE) {
429       GLuint u, tgt;
430
431       save->ActiveUnit = ctx->Texture.CurrentUnit;
432       save->ClientActiveUnit = ctx->Array.ActiveTexture;
433       save->EnvMode = ctx->Texture.Unit[0].EnvMode;
434
435       if (ctx->Texture._EnabledUnits |
436           ctx->Texture._EnabledCoordUnits |
437           ctx->Texture._TexGenEnabled |
438           ctx->Texture._TexMatEnabled) {
439
440       /* Disable all texture units */
441       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
442          save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
443          save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
444          if (ctx->Texture.Unit[u].Enabled ||
445              ctx->Texture.Unit[u].TexGenEnabled) {
446             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
447             _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
448             _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
449             _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
450             _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
451             _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
452             _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
453             _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
454             _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
455             _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
456          }
457       }
458       }
459
460       /* save current texture objects for unit[0] only */
461       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
462          _mesa_reference_texobj(&save->CurrentTexture[tgt],
463                                 ctx->Texture.Unit[0].CurrentTex[tgt]);
464       }
465
466       /* set defaults for unit[0] */
467       _mesa_ActiveTextureARB(GL_TEXTURE0);
468       _mesa_ClientActiveTextureARB(GL_TEXTURE0);
469       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
470    }
471
472    if (state & META_TRANSFORM) {
473       GLuint activeTexture = ctx->Texture.CurrentUnit;
474       _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
475                    16 * sizeof(GLfloat));
476       _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
477                    16 * sizeof(GLfloat));
478       _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
479                    16 * sizeof(GLfloat));
480       save->MatrixMode = ctx->Transform.MatrixMode;
481       /* set 1:1 vertex:pixel coordinate transform */
482       _mesa_ActiveTextureARB(GL_TEXTURE0);
483       _mesa_MatrixMode(GL_TEXTURE);
484       _mesa_LoadIdentity();
485       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
486       _mesa_MatrixMode(GL_MODELVIEW);
487       _mesa_LoadIdentity();
488       _mesa_MatrixMode(GL_PROJECTION);
489       _mesa_LoadIdentity();
490       _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
491                   0.0F, ctx->DrawBuffer->Height,
492                   -1.0F, 1.0F);
493       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
494       if (ctx->Transform.ClipPlanesEnabled) {
495          GLuint i;
496          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
497             _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
498          }
499       }
500    }
501
502    if (state & META_VERTEX) {
503       /* save vertex array object state */
504       _mesa_reference_array_object(ctx, &save->ArrayObj,
505                                    ctx->Array.ArrayObj);
506       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
507                                     ctx->Array.ArrayBufferObj);
508       /* set some default state? */
509    }
510
511    if (state & META_VIEWPORT) {
512       /* save viewport state */
513       save->ViewportX = ctx->Viewport.X;
514       save->ViewportY = ctx->Viewport.Y;
515       save->ViewportW = ctx->Viewport.Width;
516       save->ViewportH = ctx->Viewport.Height;
517       /* set viewport to match window size */
518       if (ctx->Viewport.X != 0 ||
519           ctx->Viewport.Y != 0 ||
520           ctx->Viewport.Width != ctx->DrawBuffer->Width ||
521           ctx->Viewport.Height != ctx->DrawBuffer->Height) {
522          _mesa_set_viewport(ctx, 0, 0,
523                             ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
524       }
525       /* save depth range state */
526       save->DepthNear = ctx->Viewport.Near;
527       save->DepthFar = ctx->Viewport.Far;
528       /* set depth range to default */
529       _mesa_DepthRange(0.0, 1.0);
530    }
531
532    /* misc */
533    {
534       save->Lighting = ctx->Light.Enabled;
535       if (ctx->Light.Enabled)
536          _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
537    }
538 }
539
540
541 /**
542  * Leave meta state.  This is like a light-weight version of glPopAttrib().
543  */
544 static void
545 _mesa_meta_end(GLcontext *ctx)
546 {
547    struct save_state *save = &ctx->Meta->Save;
548    const GLbitfield state = save->SavedState;
549
550    if (state & META_ALPHA_TEST) {
551       if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
552          _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
553    }
554
555    if (state & META_BLEND) {
556       if (ctx->Color.BlendEnabled != save->BlendEnabled)
557          _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
558       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
559          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
560    }
561
562    if (state & META_COLOR_MASK) {
563       if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
564          _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
565                          save->ColorMask[2], save->ColorMask[3]);
566    }
567
568    if (state & META_DEPTH_TEST) {
569       if (ctx->Depth.Test != save->Depth.Test)
570          _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
571       _mesa_DepthFunc(save->Depth.Func);
572       _mesa_DepthMask(save->Depth.Mask);
573    }
574
575    if (state & META_FOG) {
576       _mesa_set_enable(ctx, GL_FOG, save->Fog);
577    }
578
579    if (state & META_PIXEL_STORE) {
580       ctx->Pack = save->Pack;
581       ctx->Unpack = save->Unpack;
582    }
583
584    if (state & META_RASTERIZATION) {
585       _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
586       _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
587       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
588       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
589       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
590       _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
591    }
592
593    if (state & META_SCISSOR) {
594       _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
595       _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
596                     save->Scissor.Width, save->Scissor.Height);
597    }
598
599    if (state & META_SHADER) {
600       if (ctx->Extensions.ARB_vertex_program) {
601          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
602                           save->VertexProgramEnabled);
603          _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, 
604                                   save->VertexProgram);
605       }
606
607       if (ctx->Extensions.ARB_fragment_program) {
608          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
609                           save->FragmentProgramEnabled);
610          _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
611                                   save->FragmentProgram);
612       }
613
614       if (ctx->Extensions.ARB_shader_objects) {
615          _mesa_UseProgramObjectARB(save->Shader);
616       }
617    }
618
619    if (state & META_STENCIL_TEST) {
620       const struct gl_stencil_attrib *stencil = &save->Stencil;
621
622       _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
623       _mesa_ClearStencil(stencil->Clear);
624       if (ctx->Extensions.EXT_stencil_two_side) {
625          _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
626                           stencil->TestTwoSide);
627          _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
628                                     ? GL_BACK : GL_FRONT);
629       }
630       /* front state */
631       _mesa_StencilFuncSeparate(GL_FRONT,
632                                 stencil->Function[0],
633                                 stencil->Ref[0],
634                                 stencil->ValueMask[0]);
635       _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
636       _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
637                               stencil->ZFailFunc[0],
638                               stencil->ZPassFunc[0]);
639       /* back state */
640       _mesa_StencilFuncSeparate(GL_BACK,
641                                 stencil->Function[1],
642                                 stencil->Ref[1],
643                                 stencil->ValueMask[1]);
644       _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
645       _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
646                               stencil->ZFailFunc[1],
647                               stencil->ZPassFunc[1]);
648    }
649
650    if (state & META_TEXTURE) {
651       GLuint u, tgt;
652
653       ASSERT(ctx->Texture.CurrentUnit == 0);
654
655       /* restore texenv for unit[0] */
656       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
657
658       /* restore texture objects for unit[0] only */
659       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
660          _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
661                                 save->CurrentTexture[tgt]);
662       }
663
664       /* Re-enable textures, texgen */
665       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
666          if (save->TexEnabled[u]) {
667             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
668
669             if (save->TexEnabled[u] & TEXTURE_1D_BIT)
670                _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
671             if (save->TexEnabled[u] & TEXTURE_2D_BIT)
672                _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
673             if (save->TexEnabled[u] & TEXTURE_3D_BIT)
674                _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
675             if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
676                _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
677             if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
678                _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
679          }
680
681          if (save->TexGenEnabled[u]) {
682             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
683
684             if (save->TexGenEnabled[u] & S_BIT)
685                _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
686             if (save->TexGenEnabled[u] & T_BIT)
687                _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
688             if (save->TexGenEnabled[u] & R_BIT)
689                _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
690             if (save->TexGenEnabled[u] & Q_BIT)
691                _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
692          }
693       }
694
695       /* restore current unit state */
696       _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
697       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
698    }
699
700    if (state & META_TRANSFORM) {
701       GLuint activeTexture = ctx->Texture.CurrentUnit;
702       _mesa_ActiveTextureARB(GL_TEXTURE0);
703       _mesa_MatrixMode(GL_TEXTURE);
704       _mesa_LoadMatrixf(save->TextureMatrix);
705       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
706
707       _mesa_MatrixMode(GL_MODELVIEW);
708       _mesa_LoadMatrixf(save->ModelviewMatrix);
709
710       _mesa_MatrixMode(GL_PROJECTION);
711       _mesa_LoadMatrixf(save->ProjectionMatrix);
712
713       _mesa_MatrixMode(save->MatrixMode);
714
715       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
716       if (save->ClipPlanesEnabled) {
717          GLuint i;
718          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
719             if (save->ClipPlanesEnabled & (1 << i)) {
720                _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
721             }
722          }
723       }
724    }
725
726    if (state & META_VERTEX) {
727       /* restore vertex buffer object */
728       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
729       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
730
731       /* restore vertex array object */
732       _mesa_BindVertexArray(save->ArrayObj->Name);
733       _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
734    }
735
736    if (state & META_VIEWPORT) {
737       if (save->ViewportX != ctx->Viewport.X ||
738           save->ViewportY != ctx->Viewport.Y ||
739           save->ViewportW != ctx->Viewport.Width ||
740           save->ViewportH != ctx->Viewport.Height) {
741          _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
742                             save->ViewportW, save->ViewportH);
743       }
744       _mesa_DepthRange(save->DepthNear, save->DepthFar);
745    }
746
747    /* misc */
748    if (save->Lighting) {
749       _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
750    }
751    if (save->Fog) {
752       _mesa_set_enable(ctx, GL_FOG, GL_TRUE);
753    }
754 }
755
756
757 /**
758  * One-time init for a temp_texture object.
759  * Choose tex target, compute max tex size, etc.
760  */
761 static void
762 init_temp_texture(GLcontext *ctx, struct temp_texture *tex)
763 {
764    /* prefer texture rectangle */
765    if (ctx->Extensions.NV_texture_rectangle) {
766       tex->Target = GL_TEXTURE_RECTANGLE;
767       tex->MaxSize = ctx->Const.MaxTextureRectSize;
768       tex->NPOT = GL_TRUE;
769    }
770    else {
771       /* use 2D texture, NPOT if possible */
772       tex->Target = GL_TEXTURE_2D;
773       tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
774       tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
775    }
776    tex->MinSize = 16;  /* 16 x 16 at least */
777    assert(tex->MaxSize > 0);
778
779    _mesa_GenTextures(1, &tex->TexObj);
780    _mesa_BindTexture(tex->Target, tex->TexObj);
781 }
782
783
784 /**
785  * Return pointer to temp_texture info for non-bitmap ops.
786  * This does some one-time init if needed.
787  */
788 static struct temp_texture *
789 get_temp_texture(GLcontext *ctx)
790 {
791    struct temp_texture *tex = &ctx->Meta->TempTex;
792
793    if (!tex->TexObj) {
794       init_temp_texture(ctx, tex);
795    }
796
797    return tex;
798 }
799
800
801 /**
802  * Return pointer to temp_texture info for _mesa_meta_bitmap().
803  * We use a separate texture for bitmaps to reduce texture
804  * allocation/deallocation.
805  */
806 static struct temp_texture *
807 get_bitmap_temp_texture(GLcontext *ctx)
808 {
809    struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
810
811    if (!tex->TexObj) {
812       init_temp_texture(ctx, tex);
813    }
814
815    return tex;
816 }
817
818
819 /**
820  * Compute the width/height of texture needed to draw an image of the
821  * given size.  Return a flag indicating whether the current texture
822  * can be re-used (glTexSubImage2D) or if a new texture needs to be
823  * allocated (glTexImage2D).
824  * Also, compute s/t texcoords for drawing.
825  *
826  * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
827  */
828 static GLboolean
829 alloc_texture(struct temp_texture *tex,
830               GLsizei width, GLsizei height, GLenum intFormat)
831 {
832    GLboolean newTex = GL_FALSE;
833
834    ASSERT(width <= tex->MaxSize);
835    ASSERT(height <= tex->MaxSize);
836
837    if (width > tex->Width ||
838        height > tex->Height ||
839        intFormat != tex->IntFormat) {
840       /* alloc new texture (larger or different format) */
841
842       if (tex->NPOT) {
843          /* use non-power of two size */
844          tex->Width = MAX2(tex->MinSize, width);
845          tex->Height = MAX2(tex->MinSize, height);
846       }
847       else {
848          /* find power of two size */
849          GLsizei w, h;
850          w = h = tex->MinSize;
851          while (w < width)
852             w *= 2;
853          while (h < height)
854             h *= 2;
855          tex->Width = w;
856          tex->Height = h;
857       }
858
859       tex->IntFormat = intFormat;
860
861       newTex = GL_TRUE;
862    }
863
864    /* compute texcoords */
865    if (tex->Target == GL_TEXTURE_RECTANGLE) {
866       tex->Sright = (GLfloat) width;
867       tex->Ttop = (GLfloat) height;
868    }
869    else {
870       tex->Sright = (GLfloat) width / tex->Width;
871       tex->Ttop = (GLfloat) height / tex->Height;
872    }
873
874    return newTex;
875 }
876
877
878 /**
879  * Setup/load texture for glCopyPixels or glBlitFramebuffer.
880  */
881 static void
882 setup_copypix_texture(struct temp_texture *tex,
883                       GLboolean newTex,
884                       GLint srcX, GLint srcY,
885                       GLsizei width, GLsizei height, GLenum intFormat,
886                       GLenum filter)
887 {
888    _mesa_BindTexture(tex->Target, tex->TexObj);
889    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
890    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
891    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
892
893    /* copy framebuffer image to texture */
894    if (newTex) {
895       /* create new tex image */
896       if (tex->Width == width && tex->Height == height) {
897          /* create new tex with framebuffer data */
898          _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
899                               srcX, srcY, width, height, 0);
900       }
901       else {
902          /* create empty texture */
903          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
904                           tex->Width, tex->Height, 0,
905                           intFormat, GL_UNSIGNED_BYTE, NULL);
906          /* load image */
907          _mesa_CopyTexSubImage2D(tex->Target, 0,
908                                  0, 0, srcX, srcY, width, height);
909       }
910    }
911    else {
912       /* replace existing tex image */
913       _mesa_CopyTexSubImage2D(tex->Target, 0,
914                               0, 0, srcX, srcY, width, height);
915    }
916 }
917
918
919 /**
920  * Setup/load texture for glDrawPixels.
921  */
922 static void
923 setup_drawpix_texture(struct temp_texture *tex,
924                       GLboolean newTex,
925                       GLenum texIntFormat,
926                       GLsizei width, GLsizei height,
927                       GLenum format, GLenum type,
928                       const GLvoid *pixels)
929 {
930    _mesa_BindTexture(tex->Target, tex->TexObj);
931    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
932    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
933    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
934
935    /* copy pixel data to texture */
936    if (newTex) {
937       /* create new tex image */
938       if (tex->Width == width && tex->Height == height) {
939          /* create new tex and load image data */
940          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
941                           tex->Width, tex->Height, 0, format, type, pixels);
942       }
943       else {
944          /* create empty texture */
945          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
946                           tex->Width, tex->Height, 0, format, type, NULL);
947          /* load image */
948          _mesa_TexSubImage2D(tex->Target, 0,
949                              0, 0, width, height, format, type, pixels);
950       }
951    }
952    else {
953       /* replace existing tex image */
954       _mesa_TexSubImage2D(tex->Target, 0,
955                           0, 0, width, height, format, type, pixels);
956    }
957 }
958
959
960
961 /**
962  * One-time init for drawing depth pixels.
963  */
964 static void
965 init_blit_depth_pixels(GLcontext *ctx)
966 {
967    static const char *program =
968       "!!ARBfp1.0\n"
969       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
970       "END \n";
971    char program2[200];
972    struct blit_state *blit = &ctx->Meta->Blit;
973    struct temp_texture *tex = get_temp_texture(ctx);
974    const char *texTarget;
975
976    assert(blit->DepthFP == 0);
977
978    /* replace %s with "RECT" or "2D" */
979    assert(strlen(program) + 4 < sizeof(program2));
980    if (tex->Target == GL_TEXTURE_RECTANGLE)
981       texTarget = "RECT";
982    else
983       texTarget = "2D";
984    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
985
986    _mesa_GenPrograms(1, &blit->DepthFP);
987    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
988    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
989                           strlen(program2), (const GLubyte *) program2);
990 }
991
992
993 /**
994  * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
995  * of texture mapping and polygon rendering.
996  */
997 void
998 _mesa_meta_blit_framebuffer(GLcontext *ctx,
999                             GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1000                             GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1001                             GLbitfield mask, GLenum filter)
1002 {
1003    struct blit_state *blit = &ctx->Meta->Blit;
1004    struct temp_texture *tex = get_temp_texture(ctx);
1005    const GLsizei maxTexSize = tex->MaxSize;
1006    const GLint srcX = MIN2(srcX0, srcX1);
1007    const GLint srcY = MIN2(srcY0, srcY1);
1008    const GLint srcW = abs(srcX1 - srcX0);
1009    const GLint srcH = abs(srcY1 - srcY0);
1010    const GLboolean srcFlipX = srcX1 < srcX0;
1011    const GLboolean srcFlipY = srcY1 < srcY0;
1012    struct vertex {
1013       GLfloat x, y, s, t;
1014    };
1015    struct vertex verts[4];
1016    GLboolean newTex;
1017
1018    if (srcW > maxTexSize || srcH > maxTexSize) {
1019       /* XXX avoid this fallback */
1020       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1021                               dstX0, dstY0, dstX1, dstY1, mask, filter);
1022       return;
1023    }
1024
1025    if (srcFlipX) {
1026       GLint tmp = dstX0;
1027       dstX0 = dstX1;
1028       dstX1 = tmp;
1029    }
1030
1031    if (srcFlipY) {
1032       GLint tmp = dstY0;
1033       dstY0 = dstY1;
1034       dstY1 = tmp;
1035    }
1036
1037    /* only scissor effects blit so save/clear all other relevant state */
1038    _mesa_meta_begin(ctx, ~META_SCISSOR);
1039
1040    if (blit->ArrayObj == 0) {
1041       /* one-time setup */
1042
1043       /* create vertex array object */
1044       _mesa_GenVertexArrays(1, &blit->ArrayObj);
1045       _mesa_BindVertexArray(blit->ArrayObj);
1046
1047       /* create vertex array buffer */
1048       _mesa_GenBuffersARB(1, &blit->VBO);
1049       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1050       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1051                           NULL, GL_DYNAMIC_DRAW_ARB);
1052
1053       /* setup vertex arrays */
1054       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1055       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1056       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1057       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1058    }
1059    else {
1060       _mesa_BindVertexArray(blit->ArrayObj);
1061       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1062    }
1063
1064    newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
1065
1066    /* vertex positions/texcoords (after texture allocation!) */
1067    {
1068       verts[0].x = (GLfloat) dstX0;
1069       verts[0].y = (GLfloat) dstY0;
1070       verts[1].x = (GLfloat) dstX1;
1071       verts[1].y = (GLfloat) dstY0;
1072       verts[2].x = (GLfloat) dstX1;
1073       verts[2].y = (GLfloat) dstY1;
1074       verts[3].x = (GLfloat) dstX0;
1075       verts[3].y = (GLfloat) dstY1;
1076
1077       verts[0].s = 0.0F;
1078       verts[0].t = 0.0F;
1079       verts[1].s = tex->Sright;
1080       verts[1].t = 0.0F;
1081       verts[2].s = tex->Sright;
1082       verts[2].t = tex->Ttop;
1083       verts[3].s = 0.0F;
1084       verts[3].t = tex->Ttop;
1085
1086       /* upload new vertex data */
1087       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1088    }
1089
1090    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1091
1092    if (mask & GL_COLOR_BUFFER_BIT) {
1093       setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
1094                             GL_RGBA, filter);
1095       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1096       mask &= ~GL_COLOR_BUFFER_BIT;
1097    }
1098
1099    if (mask & GL_DEPTH_BUFFER_BIT) {
1100       GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint));
1101       if (tmp) {
1102          if (!blit->DepthFP)
1103             init_blit_depth_pixels(ctx);
1104
1105          /* maybe change tex format here */
1106          newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
1107
1108          _mesa_ReadPixels(srcX, srcY, srcW, srcH,
1109                           GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1110
1111          setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
1112                                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1113
1114          _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1115          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1116          _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1117          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1118          _mesa_DepthFunc(GL_ALWAYS);
1119          _mesa_DepthMask(GL_TRUE);
1120
1121          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1122          mask &= ~GL_DEPTH_BUFFER_BIT;
1123
1124          _mesa_free(tmp);
1125       }
1126    }
1127
1128    if (mask & GL_STENCIL_BUFFER_BIT) {
1129       /* XXX can't easily do stencil */
1130    }
1131
1132    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1133
1134    _mesa_meta_end(ctx);
1135
1136    if (mask) {
1137       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1138                               dstX0, dstY0, dstX1, dstY1, mask, filter);
1139    }
1140 }
1141
1142
1143 /**
1144  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1145  */
1146 void
1147 _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
1148 {
1149    struct clear_state *clear = &ctx->Meta->Clear;
1150    struct vertex {
1151       GLfloat x, y, z, r, g, b, a;
1152    };
1153    struct vertex verts[4];
1154    /* save all state but scissor, pixel pack/unpack */
1155    GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
1156
1157    if (buffers & BUFFER_BITS_COLOR) {
1158       /* if clearing color buffers, don't save/restore colormask */
1159       metaSave -= META_COLOR_MASK;
1160    }
1161
1162    _mesa_meta_begin(ctx, metaSave);
1163
1164    if (clear->ArrayObj == 0) {
1165       /* one-time setup */
1166
1167       /* create vertex array object */
1168       _mesa_GenVertexArrays(1, &clear->ArrayObj);
1169       _mesa_BindVertexArray(clear->ArrayObj);
1170
1171       /* create vertex array buffer */
1172       _mesa_GenBuffersARB(1, &clear->VBO);
1173       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1174       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1175                           NULL, GL_DYNAMIC_DRAW_ARB);
1176
1177       /* setup vertex arrays */
1178       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1179       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1180       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1181       _mesa_EnableClientState(GL_COLOR_ARRAY);
1182    }
1183    else {
1184       _mesa_BindVertexArray(clear->ArrayObj);
1185       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1186    }
1187
1188    /* GL_COLOR_BUFFER_BIT */
1189    if (buffers & BUFFER_BITS_COLOR) {
1190       /* leave colormask, glDrawBuffer state as-is */
1191    }
1192    else {
1193       ASSERT(metaSave & META_COLOR_MASK);
1194       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1195    }
1196
1197    /* GL_DEPTH_BUFFER_BIT */
1198    if (buffers & BUFFER_BIT_DEPTH) {
1199       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1200       _mesa_DepthFunc(GL_ALWAYS);
1201       _mesa_DepthMask(GL_TRUE);
1202    }
1203    else {
1204       assert(!ctx->Depth.Test);
1205    }
1206
1207    /* GL_STENCIL_BUFFER_BIT */
1208    if (buffers & BUFFER_BIT_STENCIL) {
1209       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1210       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1211                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
1212       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1213                                 ctx->Stencil.Clear & 0x7fffffff,
1214                                 ctx->Stencil.WriteMask[0]);
1215    }
1216    else {
1217       assert(!ctx->Stencil.Enabled);
1218    }
1219
1220    /* vertex positions/colors */
1221    {
1222       const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
1223       const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
1224       const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
1225       const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
1226       const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
1227       GLuint i;
1228
1229       verts[0].x = x0;
1230       verts[0].y = y0;
1231       verts[0].z = z;
1232       verts[1].x = x1;
1233       verts[1].y = y0;
1234       verts[1].z = z;
1235       verts[2].x = x1;
1236       verts[2].y = y1;
1237       verts[2].z = z;
1238       verts[3].x = x0;
1239       verts[3].y = y1;
1240       verts[3].z = z;
1241
1242       /* vertex colors */
1243       for (i = 0; i < 4; i++) {
1244          verts[i].r = ctx->Color.ClearColor[0];
1245          verts[i].g = ctx->Color.ClearColor[1];
1246          verts[i].b = ctx->Color.ClearColor[2];
1247          verts[i].a = ctx->Color.ClearColor[3];
1248       }
1249
1250       /* upload new vertex data */
1251       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1252    }
1253
1254    /* draw quad */
1255    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1256
1257    _mesa_meta_end(ctx);
1258 }
1259
1260
1261 /**
1262  * Meta implementation of ctx->Driver.CopyPixels() in terms
1263  * of texture mapping and polygon rendering.
1264  */
1265 void
1266 _mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
1267                        GLsizei width, GLsizei height,
1268                        GLint dstX, GLint dstY, GLenum type)
1269 {
1270    struct copypix_state *copypix = &ctx->Meta->CopyPix;
1271    struct temp_texture *tex = get_temp_texture(ctx);
1272    struct vertex {
1273       GLfloat x, y, z, s, t;
1274    };
1275    struct vertex verts[4];
1276    GLboolean newTex;
1277    GLenum intFormat = GL_RGBA;
1278
1279    if (type != GL_COLOR ||
1280        ctx->_ImageTransferState ||
1281        ctx->Fog.Enabled ||
1282        width > tex->MaxSize ||
1283        height > tex->MaxSize) {
1284       /* XXX avoid this fallback */
1285       _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
1286       return;
1287    }
1288
1289    /* Most GL state applies to glCopyPixels, but a there's a few things
1290     * we need to override:
1291     */
1292    _mesa_meta_begin(ctx, (META_RASTERIZATION |
1293                           META_SHADER |
1294                           META_TEXTURE |
1295                           META_TRANSFORM |
1296                           META_VERTEX |
1297                           META_VIEWPORT));
1298
1299    if (copypix->ArrayObj == 0) {
1300       /* one-time setup */
1301
1302       /* create vertex array object */
1303       _mesa_GenVertexArrays(1, &copypix->ArrayObj);
1304       _mesa_BindVertexArray(copypix->ArrayObj);
1305
1306       /* create vertex array buffer */
1307       _mesa_GenBuffersARB(1, &copypix->VBO);
1308       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1309       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1310                           NULL, GL_DYNAMIC_DRAW_ARB);
1311
1312       /* setup vertex arrays */
1313       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1314       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1315       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1316       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1317    }
1318    else {
1319       _mesa_BindVertexArray(copypix->ArrayObj);
1320       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1321    }
1322
1323    newTex = alloc_texture(tex, width, height, intFormat);
1324
1325    /* vertex positions, texcoords (after texture allocation!) */
1326    {
1327       const GLfloat dstX0 = (GLfloat) dstX;
1328       const GLfloat dstY0 = (GLfloat) dstY;
1329       const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
1330       const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
1331       const GLfloat z = ctx->Current.RasterPos[2];
1332
1333       verts[0].x = dstX0;
1334       verts[0].y = dstY0;
1335       verts[0].z = z;
1336       verts[0].s = 0.0F;
1337       verts[0].t = 0.0F;
1338       verts[1].x = dstX1;
1339       verts[1].y = dstY0;
1340       verts[1].z = z;
1341       verts[1].s = tex->Sright;
1342       verts[1].t = 0.0F;
1343       verts[2].x = dstX1;
1344       verts[2].y = dstY1;
1345       verts[2].z = z;
1346       verts[2].s = tex->Sright;
1347       verts[2].t = tex->Ttop;
1348       verts[3].x = dstX0;
1349       verts[3].y = dstY1;
1350       verts[3].z = z;
1351       verts[3].s = 0.0F;
1352       verts[3].t = tex->Ttop;
1353
1354       /* upload new vertex data */
1355       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1356    }
1357
1358    /* Alloc/setup texture */
1359    setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
1360                          GL_RGBA, GL_NEAREST);
1361
1362    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1363
1364    /* draw textured quad */
1365    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1366
1367    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1368
1369    _mesa_meta_end(ctx);
1370 }
1371
1372
1373
1374 /**
1375  * When the glDrawPixels() image size is greater than the max rectangle
1376  * texture size we use this function to break the glDrawPixels() image
1377  * into tiles which fit into the max texture size.
1378  */
1379 static void
1380 tiled_draw_pixels(GLcontext *ctx,
1381                   GLint tileSize,
1382                   GLint x, GLint y, GLsizei width, GLsizei height,
1383                   GLenum format, GLenum type,
1384                   const struct gl_pixelstore_attrib *unpack,
1385                   const GLvoid *pixels)
1386 {
1387    struct gl_pixelstore_attrib tileUnpack = *unpack;
1388    GLint i, j;
1389
1390    if (tileUnpack.RowLength == 0)
1391       tileUnpack.RowLength = width;
1392
1393    for (i = 0; i < width; i += tileSize) {
1394       const GLint tileWidth = MIN2(tileSize, width - i);
1395       const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
1396
1397       tileUnpack.SkipPixels = unpack->SkipPixels + i;
1398
1399       for (j = 0; j < height; j += tileSize) {
1400          const GLint tileHeight = MIN2(tileSize, height - j);
1401          const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
1402
1403          tileUnpack.SkipRows = unpack->SkipRows + j;
1404
1405          _mesa_meta_draw_pixels(ctx, tileX, tileY,
1406                                 tileWidth, tileHeight,
1407                                 format, type, &tileUnpack, pixels);
1408       }
1409    }
1410 }
1411
1412
1413 /**
1414  * One-time init for drawing stencil pixels.
1415  */
1416 static void
1417 init_draw_stencil_pixels(GLcontext *ctx)
1418 {
1419    /* This program is run eight times, once for each stencil bit.
1420     * The stencil values to draw are found in an 8-bit alpha texture.
1421     * We read the texture/stencil value and test if bit 'b' is set.
1422     * If the bit is not set, use KIL to kill the fragment.
1423     * Finally, we use the stencil test to update the stencil buffer.
1424     *
1425     * The basic algorithm for checking if a bit is set is:
1426     *   if (is_odd(value / (1 << bit)))
1427     *      result is one (or non-zero).
1428     *   else
1429     *      result is zero.
1430     * The program parameter contains three values:
1431     *   parm.x = 255 / (1 << bit)
1432     *   parm.y = 0.5
1433     *   parm.z = 0.0
1434     */
1435    static const char *program =
1436       "!!ARBfp1.0\n"
1437       "PARAM parm = program.local[0]; \n"
1438       "TEMP t; \n"
1439       "TEX t, fragment.texcoord[0], texture[0], %s; \n"   /* NOTE %s here! */
1440       "# t = t * 255 / bit \n"
1441       "MUL t.x, t.a, parm.x; \n"
1442       "# t = (int) t \n"
1443       "FRC t.y, t.x; \n"
1444       "SUB t.x, t.x, t.y; \n"
1445       "# t = t * 0.5 \n"
1446       "MUL t.x, t.x, parm.y; \n"
1447       "# t = fract(t.x) \n"
1448       "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
1449       "# t.x = (t.x == 0 ? 1 : 0) \n"
1450       "SGE t.x, -t.x, parm.z; \n"
1451       "KIL -t.x; \n"
1452       "# for debug only \n"
1453       "#MOV result.color, t.x; \n"
1454       "END \n";
1455    char program2[1000];
1456    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1457    struct temp_texture *tex = get_temp_texture(ctx);
1458    const char *texTarget;
1459
1460    assert(drawpix->StencilFP == 0);
1461
1462    /* replace %s with "RECT" or "2D" */
1463    assert(strlen(program) + 4 < sizeof(program2));
1464    if (tex->Target == GL_TEXTURE_RECTANGLE)
1465       texTarget = "RECT";
1466    else
1467       texTarget = "2D";
1468    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1469
1470    _mesa_GenPrograms(1, &drawpix->StencilFP);
1471    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1472    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1473                           strlen(program2), (const GLubyte *) program2);
1474 }
1475
1476
1477 /**
1478  * One-time init for drawing depth pixels.
1479  */
1480 static void
1481 init_draw_depth_pixels(GLcontext *ctx)
1482 {
1483    static const char *program =
1484       "!!ARBfp1.0\n"
1485       "PARAM color = program.local[0]; \n"
1486       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1487       "MOV result.color, color; \n"
1488       "END \n";
1489    char program2[200];
1490    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1491    struct temp_texture *tex = get_temp_texture(ctx);
1492    const char *texTarget;
1493
1494    assert(drawpix->DepthFP == 0);
1495
1496    /* replace %s with "RECT" or "2D" */
1497    assert(strlen(program) + 4 < sizeof(program2));
1498    if (tex->Target == GL_TEXTURE_RECTANGLE)
1499       texTarget = "RECT";
1500    else
1501       texTarget = "2D";
1502    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1503
1504    _mesa_GenPrograms(1, &drawpix->DepthFP);
1505    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1506    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1507                           strlen(program2), (const GLubyte *) program2);
1508 }
1509
1510
1511 /**
1512  * Meta implementation of ctx->Driver.DrawPixels() in terms
1513  * of texture mapping and polygon rendering.
1514  */
1515 void
1516 _mesa_meta_draw_pixels(GLcontext *ctx,
1517                        GLint x, GLint y, GLsizei width, GLsizei height,
1518                        GLenum format, GLenum type,
1519                        const struct gl_pixelstore_attrib *unpack,
1520                        const GLvoid *pixels)
1521 {
1522    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1523    struct temp_texture *tex = get_temp_texture(ctx);
1524    const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
1525    const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
1526    struct vertex {
1527       GLfloat x, y, z, s, t;
1528    };
1529    struct vertex verts[4];
1530    GLenum texIntFormat;
1531    GLboolean fallback, newTex;
1532    GLbitfield metaExtraSave = 0x0;
1533
1534    /*
1535     * Determine if we can do the glDrawPixels with texture mapping.
1536     */
1537    fallback = GL_FALSE;
1538    if (ctx->_ImageTransferState ||
1539        ctx->Fog.Enabled) {
1540       fallback = GL_TRUE;
1541    }
1542
1543    if (_mesa_is_color_format(format)) {
1544       /* use more compact format when possible */
1545       /* XXX disable special case for GL_LUMINANCE for now to work around
1546        * apparent i965 driver bug (see bug #23670).
1547        */
1548       if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
1549          texIntFormat = format;
1550       else
1551          texIntFormat = GL_RGBA;
1552    }
1553    else if (_mesa_is_stencil_format(format)) {
1554       if (ctx->Extensions.ARB_fragment_program &&
1555           ctx->Pixel.IndexShift == 0 &&
1556           ctx->Pixel.IndexOffset == 0 &&
1557           type == GL_UNSIGNED_BYTE) {
1558          /* We'll store stencil as alpha.  This only works for GLubyte
1559           * image data because of how incoming values are mapped to alpha
1560           * in [0,1].
1561           */
1562          texIntFormat = GL_ALPHA;
1563          metaExtraSave = (META_COLOR_MASK |
1564                           META_DEPTH_TEST |
1565                           META_SHADER |
1566                           META_STENCIL_TEST);
1567       }
1568       else {
1569          fallback = GL_TRUE;
1570       }
1571    }
1572    else if (_mesa_is_depth_format(format)) {
1573       if (ctx->Extensions.ARB_depth_texture &&
1574           ctx->Extensions.ARB_fragment_program) {
1575          texIntFormat = GL_DEPTH_COMPONENT;
1576          metaExtraSave = (META_SHADER);
1577       }
1578       else {
1579          fallback = GL_TRUE;
1580       }
1581    }
1582    else {
1583       fallback = GL_TRUE;
1584    }
1585
1586    if (fallback) {
1587       _swrast_DrawPixels(ctx, x, y, width, height,
1588                          format, type, unpack, pixels);
1589       return;
1590    }
1591
1592    /*
1593     * Check image size against max texture size, draw as tiles if needed.
1594     */
1595    if (width > tex->MaxSize || height > tex->MaxSize) {
1596       tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
1597                         format, type, unpack, pixels);
1598       return;
1599    }
1600
1601    /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
1602     * but a there's a few things we need to override:
1603     */
1604    _mesa_meta_begin(ctx, (META_RASTERIZATION |
1605                           META_SHADER |
1606                           META_TEXTURE |
1607                           META_TRANSFORM |
1608                           META_VERTEX |
1609                           META_VIEWPORT |
1610                           metaExtraSave));
1611
1612    if (drawpix->ArrayObj == 0) {
1613       /* one-time setup */
1614
1615       /* create vertex array object */
1616       _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
1617       _mesa_BindVertexArray(drawpix->ArrayObj);
1618
1619       /* create vertex array buffer */
1620       _mesa_GenBuffersARB(1, &drawpix->VBO);
1621       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1622       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1623                           NULL, GL_DYNAMIC_DRAW_ARB);
1624
1625       /* setup vertex arrays */
1626       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1627       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1628       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1629       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1630    }
1631    else {
1632       _mesa_BindVertexArray(drawpix->ArrayObj);
1633       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1634    }
1635
1636    newTex = alloc_texture(tex, width, height, texIntFormat);
1637
1638    /* vertex positions, texcoords (after texture allocation!) */
1639    {
1640       const GLfloat x0 = (GLfloat) x;
1641       const GLfloat y0 = (GLfloat) y;
1642       const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
1643       const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
1644       const GLfloat z = ctx->Current.RasterPos[2];
1645
1646       verts[0].x = x0;
1647       verts[0].y = y0;
1648       verts[0].z = z;
1649       verts[0].s = 0.0F;
1650       verts[0].t = 0.0F;
1651       verts[1].x = x1;
1652       verts[1].y = y0;
1653       verts[1].z = z;
1654       verts[1].s = tex->Sright;
1655       verts[1].t = 0.0F;
1656       verts[2].x = x1;
1657       verts[2].y = y1;
1658       verts[2].z = z;
1659       verts[2].s = tex->Sright;
1660       verts[2].t = tex->Ttop;
1661       verts[3].x = x0;
1662       verts[3].y = y1;
1663       verts[3].z = z;
1664       verts[3].s = 0.0F;
1665       verts[3].t = tex->Ttop;
1666
1667       /* upload new vertex data */
1668       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1669    }
1670
1671    /* set given unpack params */
1672    ctx->Unpack = *unpack;
1673
1674    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1675
1676    if (_mesa_is_stencil_format(format)) {
1677       /* Drawing stencil */
1678       GLint bit;
1679
1680       if (!drawpix->StencilFP)
1681          init_draw_stencil_pixels(ctx);
1682
1683       setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1684                             GL_ALPHA, type, pixels);
1685
1686       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1687
1688       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1689
1690       /* set all stencil bits to 0 */
1691       _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1692       _mesa_StencilFunc(GL_ALWAYS, 0, 255);
1693       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1694   
1695       /* set stencil bits to 1 where needed */
1696       _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1697
1698       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1699       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1700
1701       for (bit = 0; bit < ctx->Visual.stencilBits; bit++) {
1702          const GLuint mask = 1 << bit;
1703          if (mask & origStencilMask) {
1704             _mesa_StencilFunc(GL_ALWAYS, mask, mask);
1705             _mesa_StencilMask(mask);
1706
1707             _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1708                                              255.0 / mask, 0.5, 0.0, 0.0);
1709
1710             _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1711          }
1712       }
1713    }
1714    else if (_mesa_is_depth_format(format)) {
1715       /* Drawing depth */
1716       if (!drawpix->DepthFP)
1717          init_draw_depth_pixels(ctx);
1718
1719       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1720       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1721
1722       /* polygon color = current raster color */
1723       _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1724                                         ctx->Current.RasterColor);
1725
1726       setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1727                             format, type, pixels);
1728
1729       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1730    }
1731    else {
1732       /* Drawing RGBA */
1733       setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1734                             format, type, pixels);
1735       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1736    }
1737
1738    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1739
1740    /* restore unpack params */
1741    ctx->Unpack = unpackSave;
1742
1743    _mesa_meta_end(ctx);
1744 }
1745
1746
1747 /**
1748  * Do glBitmap with a alpha texture quad.  Use the alpha test to
1749  * cull the 'off' bits.  If alpha test is already enabled, fall back
1750  * to swrast (should be a rare case).
1751  * A bitmap cache as in the gallium/mesa state tracker would
1752  * improve performance a lot.
1753  */
1754 void
1755 _mesa_meta_bitmap(GLcontext *ctx,
1756                   GLint x, GLint y, GLsizei width, GLsizei height,
1757                   const struct gl_pixelstore_attrib *unpack,
1758                   const GLubyte *bitmap1)
1759 {
1760    struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
1761    struct temp_texture *tex = get_bitmap_temp_texture(ctx);
1762    const GLenum texIntFormat = GL_ALPHA;
1763    const struct gl_pixelstore_attrib unpackSave = *unpack;
1764    struct vertex {
1765       GLfloat x, y, z, s, t, r, g, b, a;
1766    };
1767    struct vertex verts[4];
1768    GLboolean newTex;
1769    GLubyte *bitmap8;
1770
1771    /*
1772     * Check if swrast fallback is needed.
1773     */
1774    if (ctx->_ImageTransferState ||
1775        ctx->Color.AlphaEnabled ||
1776        ctx->Fog.Enabled ||
1777        ctx->Texture._EnabledUnits ||
1778        width > tex->MaxSize ||
1779        height > tex->MaxSize) {
1780       _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
1781       return;
1782    }
1783
1784    /* Most GL state applies to glBitmap (like blending, stencil, etc),
1785     * but a there's a few things we need to override:
1786     */
1787    _mesa_meta_begin(ctx, (META_ALPHA_TEST |
1788                           META_PIXEL_STORE |
1789                           META_RASTERIZATION |
1790                           META_SHADER |
1791                           META_TEXTURE |
1792                           META_TRANSFORM |
1793                           META_VERTEX |
1794                           META_VIEWPORT));
1795
1796    if (bitmap->ArrayObj == 0) {
1797       /* one-time setup */
1798
1799       /* create vertex array object */
1800       _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
1801       _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
1802
1803       /* create vertex array buffer */
1804       _mesa_GenBuffersARB(1, &bitmap->VBO);
1805       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1806       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1807                           NULL, GL_DYNAMIC_DRAW_ARB);
1808
1809       /* setup vertex arrays */
1810       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1811       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1812       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1813       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1814       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1815       _mesa_EnableClientState(GL_COLOR_ARRAY);
1816    }
1817    else {
1818       _mesa_BindVertexArray(bitmap->ArrayObj);
1819       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1820    }
1821
1822    newTex = alloc_texture(tex, width, height, texIntFormat);
1823
1824    /* vertex positions, texcoords, colors (after texture allocation!) */
1825    {
1826       const GLfloat x0 = (GLfloat) x;
1827       const GLfloat y0 = (GLfloat) y;
1828       const GLfloat x1 = (GLfloat) (x + width);
1829       const GLfloat y1 = (GLfloat) (y + height);
1830       const GLfloat z = ctx->Current.RasterPos[2];
1831       GLuint i;
1832
1833       verts[0].x = x0;
1834       verts[0].y = y0;
1835       verts[0].z = z;
1836       verts[0].s = 0.0F;
1837       verts[0].t = 0.0F;
1838       verts[1].x = x1;
1839       verts[1].y = y0;
1840       verts[1].z = z;
1841       verts[1].s = tex->Sright;
1842       verts[1].t = 0.0F;
1843       verts[2].x = x1;
1844       verts[2].y = y1;
1845       verts[2].z = z;
1846       verts[2].s = tex->Sright;
1847       verts[2].t = tex->Ttop;
1848       verts[3].x = x0;
1849       verts[3].y = y1;
1850       verts[3].z = z;
1851       verts[3].s = 0.0F;
1852       verts[3].t = tex->Ttop;
1853
1854       for (i = 0; i < 4; i++) {
1855          verts[i].r = ctx->Current.RasterColor[0];
1856          verts[i].g = ctx->Current.RasterColor[1];
1857          verts[i].b = ctx->Current.RasterColor[2];
1858          verts[i].a = ctx->Current.RasterColor[3];
1859       }
1860
1861       /* upload new vertex data */
1862       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1863    }
1864
1865    bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
1866    if (!bitmap1)
1867       return;
1868
1869    bitmap8 = (GLubyte *) _mesa_calloc(width * height);
1870    if (bitmap8) {
1871       _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
1872                           bitmap8, width, 0xff);
1873
1874       _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1875
1876       _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
1877       _mesa_AlphaFunc(GL_GREATER, 0.0);
1878
1879       setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1880                             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
1881
1882       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1883
1884       _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1885
1886       _mesa_free(bitmap8);
1887    }
1888
1889    _mesa_unmap_pbo_source(ctx, &unpackSave);
1890
1891    _mesa_meta_end(ctx);
1892 }
1893
1894
1895 void
1896 _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
1897                            struct gl_texture_object *texObj)
1898 {
1899    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
1900    struct vertex {
1901       GLfloat x, y, s, t, r;
1902    };
1903    struct vertex verts[4];
1904    const GLuint baseLevel = texObj->BaseLevel;
1905    const GLuint maxLevel = texObj->MaxLevel;
1906    const GLenum minFilterSave = texObj->MinFilter;
1907    const GLenum magFilterSave = texObj->MagFilter;
1908    const GLuint fboSave = ctx->DrawBuffer->Name;
1909    GLenum faceTarget;
1910    GLuint level;
1911    GLuint border = 0;
1912
1913    /* check for fallbacks */
1914    if (!ctx->Extensions.EXT_framebuffer_object) {
1915       _mesa_generate_mipmap(ctx, target, texObj);
1916       return;
1917    }
1918
1919    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
1920        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
1921       faceTarget = target;
1922       target = GL_TEXTURE_CUBE_MAP;
1923    }
1924    else {
1925       faceTarget = target;
1926    }
1927
1928    _mesa_meta_begin(ctx, META_ALL);
1929
1930    if (mipmap->ArrayObj == 0) {
1931       /* one-time setup */
1932
1933       /* create vertex array object */
1934       _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
1935       _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
1936
1937       /* create vertex array buffer */
1938       _mesa_GenBuffersARB(1, &mipmap->VBO);
1939       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
1940       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1941                           NULL, GL_DYNAMIC_DRAW_ARB);
1942
1943       /* setup vertex arrays */
1944       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1945       _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1946       _mesa_EnableClientState(GL_VERTEX_ARRAY);
1947       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1948    }
1949    else {
1950       _mesa_BindVertexArray(mipmap->ArrayObj);
1951       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
1952    }
1953
1954    if (!mipmap->FBO) {
1955       /* Bind the new renderbuffer to the color attachment point. */
1956       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
1957    }
1958
1959    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
1960
1961    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1962    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1963    _mesa_set_enable(ctx, target, GL_TRUE);
1964
1965    /* setup texcoords once (XXX what about border?) */
1966    switch (faceTarget) {
1967    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1968       break;
1969    case GL_TEXTURE_2D:
1970       verts[0].s = 0.0F;
1971       verts[0].t = 0.0F;
1972       verts[0].r = 0.0F;
1973       verts[1].s = 1.0F;
1974       verts[1].t = 0.0F;
1975       verts[1].r = 0.0F;
1976       verts[2].s = 1.0F;
1977       verts[2].t = 1.0F;
1978       verts[2].r = 0.0F;
1979       verts[3].s = 0.0F;
1980       verts[3].t = 1.0F;
1981       verts[3].r = 0.0F;
1982       break;
1983    }
1984
1985
1986    for (level = baseLevel + 1; level <= maxLevel; level++) {
1987       const struct gl_texture_image *srcImage;
1988       const GLuint srcLevel = level - 1;
1989       GLsizei srcWidth, srcHeight;
1990       GLsizei newWidth, newHeight;
1991       GLenum status;
1992
1993       srcImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
1994       assert(srcImage->Border == 0); /* XXX we can fix this */
1995
1996       srcWidth = srcImage->Width - 2 * border;
1997       srcHeight = srcImage->Height - 2 * border;
1998
1999       newWidth = MAX2(1, srcWidth / 2) + 2 * border;
2000       newHeight = MAX2(1, srcHeight / 2) + 2 * border;
2001
2002       if (newWidth == srcImage->Width && newHeight == srcImage->Height) {
2003          break;
2004       }
2005
2006       /* Create empty image */
2007       _mesa_TexImage2D(GL_TEXTURE_2D, level, srcImage->InternalFormat,
2008                        newWidth, newHeight, border,
2009                        GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2010
2011       /* vertex positions */
2012       {
2013          verts[0].x = 0.0F;
2014          verts[0].y = 0.0F;
2015          verts[1].x = (GLfloat) newWidth;
2016          verts[1].y = 0.0F;
2017          verts[2].x = (GLfloat) newWidth;
2018          verts[2].y = (GLfloat) newHeight;
2019          verts[3].x = 0.0F;
2020          verts[3].y = (GLfloat) newHeight;
2021
2022          /* upload new vertex data */
2023          _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2024       }
2025
2026       /* limit sampling to src level */
2027       _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, srcLevel);
2028       _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, srcLevel);
2029
2030       /* Set to draw into the current level */
2031       _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2032                                     GL_COLOR_ATTACHMENT0_EXT,
2033                                     target,
2034                                     texObj->Name,
2035                                     level);
2036
2037       /* Choose to render to the color attachment. */
2038       _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
2039
2040       status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
2041       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2042          abort();
2043          break;
2044       }
2045
2046       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2047    }
2048
2049    _mesa_meta_end(ctx);
2050
2051    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
2052    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
2053
2054    /* restore (XXX add to meta_begin/end()? */
2055    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2056 }
2057
2058
2059 #if FEATURE_OES_draw_texture
2060
2061
2062 /**
2063  * Meta implementation of ctx->Driver.DrawTex() in terms
2064  * of polygon rendering.
2065  */
2066 void
2067 _mesa_meta_draw_tex(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z,
2068                     GLfloat width, GLfloat height)
2069 {
2070    struct drawtex_state *drawtex = &ctx->Meta->DrawTex;
2071    struct vertex {
2072       GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2];
2073    };
2074    struct vertex verts[4];
2075    GLuint i;
2076
2077    _mesa_meta_begin(ctx, (META_RASTERIZATION |
2078                           META_SHADER |
2079                           META_TRANSFORM |
2080                           META_VERTEX |
2081                           META_VIEWPORT));
2082
2083    if (drawtex->ArrayObj == 0) {
2084       /* one-time setup */
2085       GLint active_texture;
2086
2087       /* create vertex array object */
2088       _mesa_GenVertexArrays(1, &drawtex->ArrayObj);
2089       _mesa_BindVertexArray(drawtex->ArrayObj);
2090
2091       /* create vertex array buffer */
2092       _mesa_GenBuffersARB(1, &drawtex->VBO);
2093       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
2094       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2095                           NULL, GL_DYNAMIC_DRAW_ARB);
2096
2097       /* client active texture is not part of the array object */
2098       active_texture = ctx->Array.ActiveTexture;
2099
2100       /* setup vertex arrays */
2101       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2102       _mesa_EnableClientState(GL_VERTEX_ARRAY);
2103       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
2104          _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i);
2105          _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
2106          _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2107       }
2108
2109       /* restore client active texture */
2110       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture);
2111    }
2112    else {
2113       _mesa_BindVertexArray(drawtex->ArrayObj);
2114       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
2115    }
2116
2117    /* vertex positions, texcoords */
2118    {
2119       const GLfloat x1 = x + width;
2120       const GLfloat y1 = y + height;
2121
2122       verts[0].x = x;
2123       verts[0].y = y;
2124       verts[0].z = z;
2125
2126       verts[1].x = x1;
2127       verts[1].y = y;
2128       verts[1].z = z;
2129
2130       verts[2].x = x1;
2131       verts[2].y = y1;
2132       verts[2].z = z;
2133
2134       verts[3].x = x;
2135       verts[3].y = y1;
2136       verts[3].z = z;
2137
2138       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
2139          const struct gl_texture_object *texObj;
2140          const struct gl_texture_image *texImage;
2141          GLfloat s, t, s1, t1;
2142          GLuint tw, th;
2143
2144          if (!ctx->Texture.Unit[i]._ReallyEnabled) {
2145             GLuint j;
2146             for (j = 0; j < 4; j++) {
2147                verts[j].st[i][0] = 0.0f;
2148                verts[j].st[i][1] = 0.0f;
2149             }
2150             continue;
2151          }
2152
2153          texObj = ctx->Texture.Unit[i]._Current;
2154          texImage = texObj->Image[0][texObj->BaseLevel];
2155          tw = texImage->Width2;
2156          th = texImage->Height2;
2157
2158          s = (GLfloat) texObj->CropRect[0] / tw;
2159          t = (GLfloat) texObj->CropRect[1] / th;
2160          s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw;
2161          t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th;
2162
2163          verts[0].st[i][0] = s;
2164          verts[0].st[i][1] = t;
2165
2166          verts[1].st[i][0] = s1;
2167          verts[1].st[i][1] = t;
2168
2169          verts[2].st[i][0] = s1;
2170          verts[2].st[i][1] = t1;
2171
2172          verts[3].st[i][0] = s;
2173          verts[3].st[i][1] = t1;
2174       }
2175
2176       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2177    }
2178
2179    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2180
2181    _mesa_meta_end(ctx);
2182 }
2183
2184
2185 #endif /* FEATURE_OES_draw_texture */