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