Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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