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