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