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