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