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