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