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