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