2 * Mesa 3-D graphics library
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
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.
34 #include "main/glheader.h"
35 #include "main/mtypes.h"
36 #include "main/imports.h"
37 #include "main/arrayobj.h"
38 #include "main/blend.h"
39 #include "main/bufferobj.h"
40 #include "main/buffers.h"
41 #include "main/depth.h"
42 #include "main/enable.h"
43 #include "main/fbobject.h"
44 #include "main/image.h"
45 #include "main/macros.h"
46 #include "main/matrix.h"
47 #include "main/mipmap.h"
48 #include "main/polygon.h"
49 #include "main/readpix.h"
50 #include "main/scissor.h"
51 #include "main/shaders.h"
52 #include "main/stencil.h"
53 #include "main/texobj.h"
54 #include "main/texenv.h"
55 #include "main/teximage.h"
56 #include "main/texparam.h"
57 #include "main/texstate.h"
58 #include "main/varray.h"
59 #include "main/viewport.h"
60 #include "shader/program.h"
61 #include "shader/arbprogram.h"
62 #include "swrast/swrast.h"
63 #include "drivers/common/meta.h"
66 /** Return offset in bytes of the field within a vertex struct */
67 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
71 * State which we may save/restore across meta ops.
72 * XXX this may be incomplete...
76 GLbitfield SavedState; /**< bitmask of META_* flags */
78 /** META_ALPHA_TEST */
79 GLboolean AlphaEnabled;
82 GLboolean BlendEnabled;
83 GLboolean ColorLogicOpEnabled;
85 /** META_COLOR_MASK */
88 /** META_DEPTH_TEST */
89 struct gl_depthbuffer_attrib Depth;
94 /** META_PIXEL_STORE */
95 struct gl_pixelstore_attrib Pack, Unpack;
97 /** META_RASTERIZATION */
98 GLenum FrontPolygonMode, BackPolygonMode;
99 GLboolean PolygonOffset;
100 GLboolean PolygonSmooth;
101 GLboolean PolygonStipple;
102 GLboolean PolygonCull;
105 struct gl_scissor_attrib Scissor;
108 GLboolean VertexProgramEnabled;
109 struct gl_vertex_program *VertexProgram;
110 GLboolean FragmentProgramEnabled;
111 struct gl_fragment_program *FragmentProgram;
114 /** META_STENCIL_TEST */
115 struct gl_stencil_attrib Stencil;
117 /** META_TRANSFORM */
119 GLfloat ModelviewMatrix[16];
120 GLfloat ProjectionMatrix[16];
121 GLfloat TextureMatrix[16];
122 GLbitfield ClipPlanesEnabled;
126 GLuint ClientActiveUnit;
127 /** for unit[0] only */
128 struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
129 /** mask of TEXTURE_2D_BIT, etc */
130 GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
131 GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
132 GLuint EnvMode; /* unit[0] only */
135 struct gl_array_object *ArrayObj;
136 struct gl_buffer_object *ArrayBufferObj;
139 GLint ViewportX, ViewportY, ViewportW, ViewportH;
140 GLclampd DepthNear, DepthFar;
142 /** Miscellaneous (always disabled) */
148 * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
149 * This is currently shared by all the meta ops. But we could create a
150 * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
155 GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
156 GLsizei MinSize; /**< Min texture size to allocate */
157 GLsizei MaxSize; /**< Max possible texture size */
158 GLboolean NPOT; /**< Non-power of two size OK? */
159 GLsizei Width, Height; /**< Current texture size */
161 GLfloat Sright, Ttop; /**< right, top texcoords */
166 * State for glBlitFramebufer()
177 * State for glClear()
187 * State for glCopyPixels()
197 * State for glDrawPixels()
204 GLuint StencilFP; /**< Fragment program for drawing stencil images */
205 GLuint DepthFP; /**< Fragment program for drawing depth images */
210 * State for glBitmap()
216 struct temp_texture Tex; /**< separate texture from other meta ops */
221 * State for _mesa_meta_generate_mipmap()
223 struct gen_mipmap_state
232 * State for glDrawTex()
242 * All per-context meta state.
246 struct save_state Save; /**< state saved during meta-ops */
248 struct temp_texture TempTex;
250 struct blit_state Blit; /**< For _mesa_meta_blit_framebuffer() */
251 struct clear_state Clear; /**< For _mesa_meta_clear() */
252 struct copypix_state CopyPix; /**< For _mesa_meta_copy_pixels() */
253 struct drawpix_state DrawPix; /**< For _mesa_meta_draw_pixels() */
254 struct bitmap_state Bitmap; /**< For _mesa_meta_bitmap() */
255 struct gen_mipmap_state Mipmap; /**< For _mesa_meta_generate_mipmap() */
257 struct drawtex_state DrawTex; /**< For _mesa_meta_draw_tex() */
262 * Initialize meta-ops for a context.
263 * To be called once during context creation.
266 _mesa_meta_init(GLcontext *ctx)
270 ctx->Meta = CALLOC_STRUCT(gl_meta_state);
275 * Free context meta-op state.
276 * To be called once during context destruction.
279 _mesa_meta_free(GLcontext *ctx)
281 struct gl_meta_state *meta = ctx->Meta;
283 if (_mesa_get_current_context()) {
284 /* if there's no current context, these textures, buffers, etc should
285 * still get freed by _mesa_free_context_data().
288 /* the temporary texture */
289 _mesa_DeleteTextures(1, &meta->TempTex.TexObj);
291 /* glBlitFramebuffer */
292 _mesa_DeleteBuffersARB(1, & meta->Blit.VBO);
293 _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj);
294 _mesa_DeletePrograms(1, &meta->Blit.DepthFP);
297 _mesa_DeleteBuffersARB(1, & meta->Clear.VBO);
298 _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj);
301 _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO);
302 _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
305 _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO);
306 _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
307 _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP);
308 _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);
311 _mesa_DeleteBuffersARB(1, & meta->Bitmap.VBO);
312 _mesa_DeleteVertexArraysAPPLE(1, &meta->Bitmap.ArrayObj);
313 _mesa_DeleteTextures(1, &meta->Bitmap.Tex.TexObj);
316 _mesa_DeleteBuffersARB(1, & meta->DrawTex.VBO);
317 _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawTex.ArrayObj);
321 _mesa_free(ctx->Meta);
327 * Enter meta state. This is like a light-weight version of glPushAttrib
328 * but it also resets most GL state back to default values.
330 * \param state bitmask of META_* flags indicating which attribute groups
331 * to save and reset to their defaults
334 _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
336 struct save_state *save = &ctx->Meta->Save;
338 save->SavedState = state;
340 if (state & META_ALPHA_TEST) {
341 save->AlphaEnabled = ctx->Color.AlphaEnabled;
342 if (ctx->Color.AlphaEnabled)
343 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
346 if (state & META_BLEND) {
347 save->BlendEnabled = ctx->Color.BlendEnabled;
348 if (ctx->Color.BlendEnabled)
349 _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
350 save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
351 if (ctx->Color.ColorLogicOpEnabled)
352 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
355 if (state & META_COLOR_MASK) {
356 COPY_4V(save->ColorMask, ctx->Color.ColorMask);
357 if (!ctx->Color.ColorMask[0] ||
358 !ctx->Color.ColorMask[1] ||
359 !ctx->Color.ColorMask[2] ||
360 !ctx->Color.ColorMask[3])
361 _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
364 if (state & META_DEPTH_TEST) {
365 save->Depth = ctx->Depth; /* struct copy */
367 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
370 if (state & META_FOG) {
371 save->Fog = ctx->Fog.Enabled;
372 if (ctx->Fog.Enabled)
373 _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
376 if (state & META_PIXEL_STORE) {
377 save->Pack = ctx->Pack;
378 save->Unpack = ctx->Unpack;
379 ctx->Pack = ctx->DefaultPacking;
380 ctx->Unpack = ctx->DefaultPacking;
383 if (state & META_RASTERIZATION) {
384 save->FrontPolygonMode = ctx->Polygon.FrontMode;
385 save->BackPolygonMode = ctx->Polygon.BackMode;
386 save->PolygonOffset = ctx->Polygon.OffsetFill;
387 save->PolygonSmooth = ctx->Polygon.SmoothFlag;
388 save->PolygonStipple = ctx->Polygon.StippleFlag;
389 save->PolygonCull = ctx->Polygon.CullFlag;
390 _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
391 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
392 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
393 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
394 _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
397 if (state & META_SCISSOR) {
398 save->Scissor = ctx->Scissor; /* struct copy */
401 if (state & META_SHADER) {
402 if (ctx->Extensions.ARB_vertex_program) {
403 save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
404 save->VertexProgram = ctx->VertexProgram.Current;
405 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
408 if (ctx->Extensions.ARB_fragment_program) {
409 save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
410 save->FragmentProgram = ctx->FragmentProgram.Current;
411 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
414 if (ctx->Extensions.ARB_shader_objects) {
415 save->Shader = ctx->Shader.CurrentProgram ?
416 ctx->Shader.CurrentProgram->Name : 0;
417 _mesa_UseProgramObjectARB(0);
421 if (state & META_STENCIL_TEST) {
422 save->Stencil = ctx->Stencil; /* struct copy */
423 if (ctx->Stencil.Enabled)
424 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
425 /* NOTE: other stencil state not reset */
428 if (state & META_TEXTURE) {
431 save->ActiveUnit = ctx->Texture.CurrentUnit;
432 save->ClientActiveUnit = ctx->Array.ActiveTexture;
433 save->EnvMode = ctx->Texture.Unit[0].EnvMode;
435 if (ctx->Texture._EnabledUnits |
436 ctx->Texture._EnabledCoordUnits |
437 ctx->Texture._TexGenEnabled |
438 ctx->Texture._TexMatEnabled) {
440 /* Disable all texture units */
441 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
442 save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
443 save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
444 if (ctx->Texture.Unit[u].Enabled ||
445 ctx->Texture.Unit[u].TexGenEnabled) {
446 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
447 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
448 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
449 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
450 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
451 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
452 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
453 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
454 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
455 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
460 /* save current texture objects for unit[0] only */
461 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
462 _mesa_reference_texobj(&save->CurrentTexture[tgt],
463 ctx->Texture.Unit[0].CurrentTex[tgt]);
466 /* set defaults for unit[0] */
467 _mesa_ActiveTextureARB(GL_TEXTURE0);
468 _mesa_ClientActiveTextureARB(GL_TEXTURE0);
469 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
472 if (state & META_TRANSFORM) {
473 GLuint activeTexture = ctx->Texture.CurrentUnit;
474 _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
475 16 * sizeof(GLfloat));
476 _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
477 16 * sizeof(GLfloat));
478 _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
479 16 * sizeof(GLfloat));
480 save->MatrixMode = ctx->Transform.MatrixMode;
481 /* set 1:1 vertex:pixel coordinate transform */
482 _mesa_ActiveTextureARB(GL_TEXTURE0);
483 _mesa_MatrixMode(GL_TEXTURE);
484 _mesa_LoadIdentity();
485 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
486 _mesa_MatrixMode(GL_MODELVIEW);
487 _mesa_LoadIdentity();
488 _mesa_MatrixMode(GL_PROJECTION);
489 _mesa_LoadIdentity();
490 _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
491 0.0F, ctx->DrawBuffer->Height,
493 save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
494 if (ctx->Transform.ClipPlanesEnabled) {
496 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
497 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
502 if (state & META_VERTEX) {
503 /* save vertex array object state */
504 _mesa_reference_array_object(ctx, &save->ArrayObj,
505 ctx->Array.ArrayObj);
506 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
507 ctx->Array.ArrayBufferObj);
508 /* set some default state? */
511 if (state & META_VIEWPORT) {
512 /* save viewport state */
513 save->ViewportX = ctx->Viewport.X;
514 save->ViewportY = ctx->Viewport.Y;
515 save->ViewportW = ctx->Viewport.Width;
516 save->ViewportH = ctx->Viewport.Height;
517 /* set viewport to match window size */
518 if (ctx->Viewport.X != 0 ||
519 ctx->Viewport.Y != 0 ||
520 ctx->Viewport.Width != ctx->DrawBuffer->Width ||
521 ctx->Viewport.Height != ctx->DrawBuffer->Height) {
522 _mesa_set_viewport(ctx, 0, 0,
523 ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
525 /* save depth range state */
526 save->DepthNear = ctx->Viewport.Near;
527 save->DepthFar = ctx->Viewport.Far;
528 /* set depth range to default */
529 _mesa_DepthRange(0.0, 1.0);
534 save->Lighting = ctx->Light.Enabled;
535 if (ctx->Light.Enabled)
536 _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
542 * Leave meta state. This is like a light-weight version of glPopAttrib().
545 _mesa_meta_end(GLcontext *ctx)
547 struct save_state *save = &ctx->Meta->Save;
548 const GLbitfield state = save->SavedState;
550 if (state & META_ALPHA_TEST) {
551 if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
552 _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
555 if (state & META_BLEND) {
556 if (ctx->Color.BlendEnabled != save->BlendEnabled)
557 _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
558 if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
559 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
562 if (state & META_COLOR_MASK) {
563 if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
564 _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
565 save->ColorMask[2], save->ColorMask[3]);
568 if (state & META_DEPTH_TEST) {
569 if (ctx->Depth.Test != save->Depth.Test)
570 _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
571 _mesa_DepthFunc(save->Depth.Func);
572 _mesa_DepthMask(save->Depth.Mask);
575 if (state & META_FOG) {
576 _mesa_set_enable(ctx, GL_FOG, save->Fog);
579 if (state & META_PIXEL_STORE) {
580 ctx->Pack = save->Pack;
581 ctx->Unpack = save->Unpack;
584 if (state & META_RASTERIZATION) {
585 _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
586 _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
587 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
588 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
589 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
590 _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
593 if (state & META_SCISSOR) {
594 _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
595 _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
596 save->Scissor.Width, save->Scissor.Height);
599 if (state & META_SHADER) {
600 if (ctx->Extensions.ARB_vertex_program) {
601 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
602 save->VertexProgramEnabled);
603 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
604 save->VertexProgram);
607 if (ctx->Extensions.ARB_fragment_program) {
608 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
609 save->FragmentProgramEnabled);
610 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
611 save->FragmentProgram);
614 if (ctx->Extensions.ARB_shader_objects) {
615 _mesa_UseProgramObjectARB(save->Shader);
619 if (state & META_STENCIL_TEST) {
620 const struct gl_stencil_attrib *stencil = &save->Stencil;
622 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
623 _mesa_ClearStencil(stencil->Clear);
624 if (ctx->Extensions.EXT_stencil_two_side) {
625 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
626 stencil->TestTwoSide);
627 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
628 ? GL_BACK : GL_FRONT);
631 _mesa_StencilFuncSeparate(GL_FRONT,
632 stencil->Function[0],
634 stencil->ValueMask[0]);
635 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
636 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
637 stencil->ZFailFunc[0],
638 stencil->ZPassFunc[0]);
640 _mesa_StencilFuncSeparate(GL_BACK,
641 stencil->Function[1],
643 stencil->ValueMask[1]);
644 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
645 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
646 stencil->ZFailFunc[1],
647 stencil->ZPassFunc[1]);
650 if (state & META_TEXTURE) {
653 ASSERT(ctx->Texture.CurrentUnit == 0);
655 /* restore texenv for unit[0] */
656 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
658 /* restore texture objects for unit[0] only */
659 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
660 _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
661 save->CurrentTexture[tgt]);
664 /* Re-enable textures, texgen */
665 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
666 if (save->TexEnabled[u]) {
667 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
669 if (save->TexEnabled[u] & TEXTURE_1D_BIT)
670 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
671 if (save->TexEnabled[u] & TEXTURE_2D_BIT)
672 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
673 if (save->TexEnabled[u] & TEXTURE_3D_BIT)
674 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
675 if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
676 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
677 if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
678 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
681 if (save->TexGenEnabled[u]) {
682 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
684 if (save->TexGenEnabled[u] & S_BIT)
685 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
686 if (save->TexGenEnabled[u] & T_BIT)
687 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
688 if (save->TexGenEnabled[u] & R_BIT)
689 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
690 if (save->TexGenEnabled[u] & Q_BIT)
691 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
695 /* restore current unit state */
696 _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
697 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
700 if (state & META_TRANSFORM) {
701 GLuint activeTexture = ctx->Texture.CurrentUnit;
702 _mesa_ActiveTextureARB(GL_TEXTURE0);
703 _mesa_MatrixMode(GL_TEXTURE);
704 _mesa_LoadMatrixf(save->TextureMatrix);
705 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
707 _mesa_MatrixMode(GL_MODELVIEW);
708 _mesa_LoadMatrixf(save->ModelviewMatrix);
710 _mesa_MatrixMode(GL_PROJECTION);
711 _mesa_LoadMatrixf(save->ProjectionMatrix);
713 _mesa_MatrixMode(save->MatrixMode);
715 save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
716 if (save->ClipPlanesEnabled) {
718 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
719 if (save->ClipPlanesEnabled & (1 << i)) {
720 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
726 if (state & META_VERTEX) {
727 /* restore vertex buffer object */
728 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
729 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
731 /* restore vertex array object */
732 _mesa_BindVertexArray(save->ArrayObj->Name);
733 _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
736 if (state & META_VIEWPORT) {
737 if (save->ViewportX != ctx->Viewport.X ||
738 save->ViewportY != ctx->Viewport.Y ||
739 save->ViewportW != ctx->Viewport.Width ||
740 save->ViewportH != ctx->Viewport.Height) {
741 _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
742 save->ViewportW, save->ViewportH);
744 _mesa_DepthRange(save->DepthNear, save->DepthFar);
748 if (save->Lighting) {
749 _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
752 _mesa_set_enable(ctx, GL_FOG, GL_TRUE);
758 * One-time init for a temp_texture object.
759 * Choose tex target, compute max tex size, etc.
762 init_temp_texture(GLcontext *ctx, struct temp_texture *tex)
764 /* prefer texture rectangle */
765 if (ctx->Extensions.NV_texture_rectangle) {
766 tex->Target = GL_TEXTURE_RECTANGLE;
767 tex->MaxSize = ctx->Const.MaxTextureRectSize;
771 /* use 2D texture, NPOT if possible */
772 tex->Target = GL_TEXTURE_2D;
773 tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
774 tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
776 tex->MinSize = 16; /* 16 x 16 at least */
777 assert(tex->MaxSize > 0);
779 _mesa_GenTextures(1, &tex->TexObj);
780 _mesa_BindTexture(tex->Target, tex->TexObj);
785 * Return pointer to temp_texture info for non-bitmap ops.
786 * This does some one-time init if needed.
788 static struct temp_texture *
789 get_temp_texture(GLcontext *ctx)
791 struct temp_texture *tex = &ctx->Meta->TempTex;
794 init_temp_texture(ctx, tex);
802 * Return pointer to temp_texture info for _mesa_meta_bitmap().
803 * We use a separate texture for bitmaps to reduce texture
804 * allocation/deallocation.
806 static struct temp_texture *
807 get_bitmap_temp_texture(GLcontext *ctx)
809 struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
812 init_temp_texture(ctx, tex);
820 * Compute the width/height of texture needed to draw an image of the
821 * given size. Return a flag indicating whether the current texture
822 * can be re-used (glTexSubImage2D) or if a new texture needs to be
823 * allocated (glTexImage2D).
824 * Also, compute s/t texcoords for drawing.
826 * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
829 alloc_texture(struct temp_texture *tex,
830 GLsizei width, GLsizei height, GLenum intFormat)
832 GLboolean newTex = GL_FALSE;
834 ASSERT(width <= tex->MaxSize);
835 ASSERT(height <= tex->MaxSize);
837 if (width > tex->Width ||
838 height > tex->Height ||
839 intFormat != tex->IntFormat) {
840 /* alloc new texture (larger or different format) */
843 /* use non-power of two size */
844 tex->Width = MAX2(tex->MinSize, width);
845 tex->Height = MAX2(tex->MinSize, height);
848 /* find power of two size */
850 w = h = tex->MinSize;
859 tex->IntFormat = intFormat;
864 /* compute texcoords */
865 if (tex->Target == GL_TEXTURE_RECTANGLE) {
866 tex->Sright = (GLfloat) width;
867 tex->Ttop = (GLfloat) height;
870 tex->Sright = (GLfloat) width / tex->Width;
871 tex->Ttop = (GLfloat) height / tex->Height;
879 * Setup/load texture for glCopyPixels or glBlitFramebuffer.
882 setup_copypix_texture(struct temp_texture *tex,
884 GLint srcX, GLint srcY,
885 GLsizei width, GLsizei height, GLenum intFormat,
888 _mesa_BindTexture(tex->Target, tex->TexObj);
889 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
890 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
891 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
893 /* copy framebuffer image to texture */
895 /* create new tex image */
896 if (tex->Width == width && tex->Height == height) {
897 /* create new tex with framebuffer data */
898 _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
899 srcX, srcY, width, height, 0);
902 /* create empty texture */
903 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
904 tex->Width, tex->Height, 0,
905 intFormat, GL_UNSIGNED_BYTE, NULL);
907 _mesa_CopyTexSubImage2D(tex->Target, 0,
908 0, 0, srcX, srcY, width, height);
912 /* replace existing tex image */
913 _mesa_CopyTexSubImage2D(tex->Target, 0,
914 0, 0, srcX, srcY, width, height);
920 * Setup/load texture for glDrawPixels.
923 setup_drawpix_texture(struct temp_texture *tex,
926 GLsizei width, GLsizei height,
927 GLenum format, GLenum type,
928 const GLvoid *pixels)
930 _mesa_BindTexture(tex->Target, tex->TexObj);
931 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
932 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
933 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
935 /* copy pixel data to texture */
937 /* create new tex image */
938 if (tex->Width == width && tex->Height == height) {
939 /* create new tex and load image data */
940 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
941 tex->Width, tex->Height, 0, format, type, pixels);
944 /* create empty texture */
945 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
946 tex->Width, tex->Height, 0, format, type, NULL);
948 _mesa_TexSubImage2D(tex->Target, 0,
949 0, 0, width, height, format, type, pixels);
953 /* replace existing tex image */
954 _mesa_TexSubImage2D(tex->Target, 0,
955 0, 0, width, height, format, type, pixels);
962 * One-time init for drawing depth pixels.
965 init_blit_depth_pixels(GLcontext *ctx)
967 static const char *program =
969 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
972 struct blit_state *blit = &ctx->Meta->Blit;
973 struct temp_texture *tex = get_temp_texture(ctx);
974 const char *texTarget;
976 assert(blit->DepthFP == 0);
978 /* replace %s with "RECT" or "2D" */
979 assert(strlen(program) + 4 < sizeof(program2));
980 if (tex->Target == GL_TEXTURE_RECTANGLE)
984 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
986 _mesa_GenPrograms(1, &blit->DepthFP);
987 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
988 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
989 strlen(program2), (const GLubyte *) program2);
994 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
995 * of texture mapping and polygon rendering.
998 _mesa_meta_blit_framebuffer(GLcontext *ctx,
999 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1000 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1001 GLbitfield mask, GLenum filter)
1003 struct blit_state *blit = &ctx->Meta->Blit;
1004 struct temp_texture *tex = get_temp_texture(ctx);
1005 const GLsizei maxTexSize = tex->MaxSize;
1006 const GLint srcX = MIN2(srcX0, srcX1);
1007 const GLint srcY = MIN2(srcY0, srcY1);
1008 const GLint srcW = abs(srcX1 - srcX0);
1009 const GLint srcH = abs(srcY1 - srcY0);
1010 const GLboolean srcFlipX = srcX1 < srcX0;
1011 const GLboolean srcFlipY = srcY1 < srcY0;
1015 struct vertex verts[4];
1018 if (srcW > maxTexSize || srcH > maxTexSize) {
1019 /* XXX avoid this fallback */
1020 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1021 dstX0, dstY0, dstX1, dstY1, mask, filter);
1037 /* only scissor effects blit so save/clear all other relevant state */
1038 _mesa_meta_begin(ctx, ~META_SCISSOR);
1040 if (blit->ArrayObj == 0) {
1041 /* one-time setup */
1043 /* create vertex array object */
1044 _mesa_GenVertexArrays(1, &blit->ArrayObj);
1045 _mesa_BindVertexArray(blit->ArrayObj);
1047 /* create vertex array buffer */
1048 _mesa_GenBuffersARB(1, &blit->VBO);
1049 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1050 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1051 NULL, GL_DYNAMIC_DRAW_ARB);
1053 /* setup vertex arrays */
1054 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1055 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1056 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1057 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1060 _mesa_BindVertexArray(blit->ArrayObj);
1061 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1064 newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
1066 /* vertex positions/texcoords (after texture allocation!) */
1068 verts[0].x = (GLfloat) dstX0;
1069 verts[0].y = (GLfloat) dstY0;
1070 verts[1].x = (GLfloat) dstX1;
1071 verts[1].y = (GLfloat) dstY0;
1072 verts[2].x = (GLfloat) dstX1;
1073 verts[2].y = (GLfloat) dstY1;
1074 verts[3].x = (GLfloat) dstX0;
1075 verts[3].y = (GLfloat) dstY1;
1079 verts[1].s = tex->Sright;
1081 verts[2].s = tex->Sright;
1082 verts[2].t = tex->Ttop;
1084 verts[3].t = tex->Ttop;
1086 /* upload new vertex data */
1087 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1090 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1092 if (mask & GL_COLOR_BUFFER_BIT) {
1093 setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
1095 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1096 mask &= ~GL_COLOR_BUFFER_BIT;
1099 if (mask & GL_DEPTH_BUFFER_BIT) {
1100 GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint));
1103 init_blit_depth_pixels(ctx);
1105 /* maybe change tex format here */
1106 newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
1108 _mesa_ReadPixels(srcX, srcY, srcW, srcH,
1109 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1111 setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
1112 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1114 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1115 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1116 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1117 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1118 _mesa_DepthFunc(GL_ALWAYS);
1119 _mesa_DepthMask(GL_TRUE);
1121 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1122 mask &= ~GL_DEPTH_BUFFER_BIT;
1128 if (mask & GL_STENCIL_BUFFER_BIT) {
1129 /* XXX can't easily do stencil */
1132 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1134 _mesa_meta_end(ctx);
1137 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1138 dstX0, dstY0, dstX1, dstY1, mask, filter);
1144 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1147 _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
1149 struct clear_state *clear = &ctx->Meta->Clear;
1151 GLfloat x, y, z, r, g, b, a;
1153 struct vertex verts[4];
1154 /* save all state but scissor, pixel pack/unpack */
1155 GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
1157 if (buffers & BUFFER_BITS_COLOR) {
1158 /* if clearing color buffers, don't save/restore colormask */
1159 metaSave -= META_COLOR_MASK;
1162 _mesa_meta_begin(ctx, metaSave);
1164 if (clear->ArrayObj == 0) {
1165 /* one-time setup */
1167 /* create vertex array object */
1168 _mesa_GenVertexArrays(1, &clear->ArrayObj);
1169 _mesa_BindVertexArray(clear->ArrayObj);
1171 /* create vertex array buffer */
1172 _mesa_GenBuffersARB(1, &clear->VBO);
1173 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1174 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1175 NULL, GL_DYNAMIC_DRAW_ARB);
1177 /* setup vertex arrays */
1178 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1179 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1180 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1181 _mesa_EnableClientState(GL_COLOR_ARRAY);
1184 _mesa_BindVertexArray(clear->ArrayObj);
1185 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1188 /* GL_COLOR_BUFFER_BIT */
1189 if (buffers & BUFFER_BITS_COLOR) {
1190 /* leave colormask, glDrawBuffer state as-is */
1193 ASSERT(metaSave & META_COLOR_MASK);
1194 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1197 /* GL_DEPTH_BUFFER_BIT */
1198 if (buffers & BUFFER_BIT_DEPTH) {
1199 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1200 _mesa_DepthFunc(GL_ALWAYS);
1201 _mesa_DepthMask(GL_TRUE);
1204 assert(!ctx->Depth.Test);
1207 /* GL_STENCIL_BUFFER_BIT */
1208 if (buffers & BUFFER_BIT_STENCIL) {
1209 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1210 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1211 GL_REPLACE, GL_REPLACE, GL_REPLACE);
1212 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1213 ctx->Stencil.Clear & 0x7fffffff,
1214 ctx->Stencil.WriteMask[0]);
1217 assert(!ctx->Stencil.Enabled);
1220 /* vertex positions/colors */
1222 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
1223 const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
1224 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
1225 const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
1226 const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
1243 for (i = 0; i < 4; i++) {
1244 verts[i].r = ctx->Color.ClearColor[0];
1245 verts[i].g = ctx->Color.ClearColor[1];
1246 verts[i].b = ctx->Color.ClearColor[2];
1247 verts[i].a = ctx->Color.ClearColor[3];
1250 /* upload new vertex data */
1251 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1255 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1257 _mesa_meta_end(ctx);
1262 * Meta implementation of ctx->Driver.CopyPixels() in terms
1263 * of texture mapping and polygon rendering.
1266 _mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
1267 GLsizei width, GLsizei height,
1268 GLint dstX, GLint dstY, GLenum type)
1270 struct copypix_state *copypix = &ctx->Meta->CopyPix;
1271 struct temp_texture *tex = get_temp_texture(ctx);
1273 GLfloat x, y, z, s, t;
1275 struct vertex verts[4];
1277 GLenum intFormat = GL_RGBA;
1279 if (type != GL_COLOR ||
1280 ctx->_ImageTransferState ||
1282 width > tex->MaxSize ||
1283 height > tex->MaxSize) {
1284 /* XXX avoid this fallback */
1285 _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
1289 /* Most GL state applies to glCopyPixels, but a there's a few things
1290 * we need to override:
1292 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1299 if (copypix->ArrayObj == 0) {
1300 /* one-time setup */
1302 /* create vertex array object */
1303 _mesa_GenVertexArrays(1, ©pix->ArrayObj);
1304 _mesa_BindVertexArray(copypix->ArrayObj);
1306 /* create vertex array buffer */
1307 _mesa_GenBuffersARB(1, ©pix->VBO);
1308 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1309 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1310 NULL, GL_DYNAMIC_DRAW_ARB);
1312 /* setup vertex arrays */
1313 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1314 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1315 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1316 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1319 _mesa_BindVertexArray(copypix->ArrayObj);
1320 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1323 newTex = alloc_texture(tex, width, height, intFormat);
1325 /* vertex positions, texcoords (after texture allocation!) */
1327 const GLfloat dstX0 = (GLfloat) dstX;
1328 const GLfloat dstY0 = (GLfloat) dstY;
1329 const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
1330 const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
1331 const GLfloat z = ctx->Current.RasterPos[2];
1341 verts[1].s = tex->Sright;
1346 verts[2].s = tex->Sright;
1347 verts[2].t = tex->Ttop;
1352 verts[3].t = tex->Ttop;
1354 /* upload new vertex data */
1355 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1358 /* Alloc/setup texture */
1359 setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
1360 GL_RGBA, GL_NEAREST);
1362 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1364 /* draw textured quad */
1365 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1367 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1369 _mesa_meta_end(ctx);
1375 * When the glDrawPixels() image size is greater than the max rectangle
1376 * texture size we use this function to break the glDrawPixels() image
1377 * into tiles which fit into the max texture size.
1380 tiled_draw_pixels(GLcontext *ctx,
1382 GLint x, GLint y, GLsizei width, GLsizei height,
1383 GLenum format, GLenum type,
1384 const struct gl_pixelstore_attrib *unpack,
1385 const GLvoid *pixels)
1387 struct gl_pixelstore_attrib tileUnpack = *unpack;
1390 if (tileUnpack.RowLength == 0)
1391 tileUnpack.RowLength = width;
1393 for (i = 0; i < width; i += tileSize) {
1394 const GLint tileWidth = MIN2(tileSize, width - i);
1395 const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
1397 tileUnpack.SkipPixels = unpack->SkipPixels + i;
1399 for (j = 0; j < height; j += tileSize) {
1400 const GLint tileHeight = MIN2(tileSize, height - j);
1401 const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
1403 tileUnpack.SkipRows = unpack->SkipRows + j;
1405 _mesa_meta_draw_pixels(ctx, tileX, tileY,
1406 tileWidth, tileHeight,
1407 format, type, &tileUnpack, pixels);
1414 * One-time init for drawing stencil pixels.
1417 init_draw_stencil_pixels(GLcontext *ctx)
1419 /* This program is run eight times, once for each stencil bit.
1420 * The stencil values to draw are found in an 8-bit alpha texture.
1421 * We read the texture/stencil value and test if bit 'b' is set.
1422 * If the bit is not set, use KIL to kill the fragment.
1423 * Finally, we use the stencil test to update the stencil buffer.
1425 * The basic algorithm for checking if a bit is set is:
1426 * if (is_odd(value / (1 << bit)))
1427 * result is one (or non-zero).
1430 * The program parameter contains three values:
1431 * parm.x = 255 / (1 << bit)
1435 static const char *program =
1437 "PARAM parm = program.local[0]; \n"
1439 "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */
1440 "# t = t * 255 / bit \n"
1441 "MUL t.x, t.a, parm.x; \n"
1444 "SUB t.x, t.x, t.y; \n"
1446 "MUL t.x, t.x, parm.y; \n"
1447 "# t = fract(t.x) \n"
1448 "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
1449 "# t.x = (t.x == 0 ? 1 : 0) \n"
1450 "SGE t.x, -t.x, parm.z; \n"
1452 "# for debug only \n"
1453 "#MOV result.color, t.x; \n"
1455 char program2[1000];
1456 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1457 struct temp_texture *tex = get_temp_texture(ctx);
1458 const char *texTarget;
1460 assert(drawpix->StencilFP == 0);
1462 /* replace %s with "RECT" or "2D" */
1463 assert(strlen(program) + 4 < sizeof(program2));
1464 if (tex->Target == GL_TEXTURE_RECTANGLE)
1468 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1470 _mesa_GenPrograms(1, &drawpix->StencilFP);
1471 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1472 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1473 strlen(program2), (const GLubyte *) program2);
1478 * One-time init for drawing depth pixels.
1481 init_draw_depth_pixels(GLcontext *ctx)
1483 static const char *program =
1485 "PARAM color = program.local[0]; \n"
1486 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1487 "MOV result.color, color; \n"
1490 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1491 struct temp_texture *tex = get_temp_texture(ctx);
1492 const char *texTarget;
1494 assert(drawpix->DepthFP == 0);
1496 /* replace %s with "RECT" or "2D" */
1497 assert(strlen(program) + 4 < sizeof(program2));
1498 if (tex->Target == GL_TEXTURE_RECTANGLE)
1502 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1504 _mesa_GenPrograms(1, &drawpix->DepthFP);
1505 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1506 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1507 strlen(program2), (const GLubyte *) program2);
1512 * Meta implementation of ctx->Driver.DrawPixels() in terms
1513 * of texture mapping and polygon rendering.
1516 _mesa_meta_draw_pixels(GLcontext *ctx,
1517 GLint x, GLint y, GLsizei width, GLsizei height,
1518 GLenum format, GLenum type,
1519 const struct gl_pixelstore_attrib *unpack,
1520 const GLvoid *pixels)
1522 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1523 struct temp_texture *tex = get_temp_texture(ctx);
1524 const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
1525 const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
1527 GLfloat x, y, z, s, t;
1529 struct vertex verts[4];
1530 GLenum texIntFormat;
1531 GLboolean fallback, newTex;
1532 GLbitfield metaExtraSave = 0x0;
1535 * Determine if we can do the glDrawPixels with texture mapping.
1537 fallback = GL_FALSE;
1538 if (ctx->_ImageTransferState ||
1543 if (_mesa_is_color_format(format)) {
1544 /* use more compact format when possible */
1545 /* XXX disable special case for GL_LUMINANCE for now to work around
1546 * apparent i965 driver bug (see bug #23670).
1548 if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
1549 texIntFormat = format;
1551 texIntFormat = GL_RGBA;
1553 else if (_mesa_is_stencil_format(format)) {
1554 if (ctx->Extensions.ARB_fragment_program &&
1555 ctx->Pixel.IndexShift == 0 &&
1556 ctx->Pixel.IndexOffset == 0 &&
1557 type == GL_UNSIGNED_BYTE) {
1558 /* We'll store stencil as alpha. This only works for GLubyte
1559 * image data because of how incoming values are mapped to alpha
1562 texIntFormat = GL_ALPHA;
1563 metaExtraSave = (META_COLOR_MASK |
1572 else if (_mesa_is_depth_format(format)) {
1573 if (ctx->Extensions.ARB_depth_texture &&
1574 ctx->Extensions.ARB_fragment_program) {
1575 texIntFormat = GL_DEPTH_COMPONENT;
1576 metaExtraSave = (META_SHADER);
1587 _swrast_DrawPixels(ctx, x, y, width, height,
1588 format, type, unpack, pixels);
1593 * Check image size against max texture size, draw as tiles if needed.
1595 if (width > tex->MaxSize || height > tex->MaxSize) {
1596 tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
1597 format, type, unpack, pixels);
1601 /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
1602 * but a there's a few things we need to override:
1604 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1612 if (drawpix->ArrayObj == 0) {
1613 /* one-time setup */
1615 /* create vertex array object */
1616 _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
1617 _mesa_BindVertexArray(drawpix->ArrayObj);
1619 /* create vertex array buffer */
1620 _mesa_GenBuffersARB(1, &drawpix->VBO);
1621 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1622 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1623 NULL, GL_DYNAMIC_DRAW_ARB);
1625 /* setup vertex arrays */
1626 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1627 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1628 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1629 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1632 _mesa_BindVertexArray(drawpix->ArrayObj);
1633 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1636 newTex = alloc_texture(tex, width, height, texIntFormat);
1638 /* vertex positions, texcoords (after texture allocation!) */
1640 const GLfloat x0 = (GLfloat) x;
1641 const GLfloat y0 = (GLfloat) y;
1642 const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
1643 const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
1644 const GLfloat z = ctx->Current.RasterPos[2];
1654 verts[1].s = tex->Sright;
1659 verts[2].s = tex->Sright;
1660 verts[2].t = tex->Ttop;
1665 verts[3].t = tex->Ttop;
1667 /* upload new vertex data */
1668 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1671 /* set given unpack params */
1672 ctx->Unpack = *unpack;
1674 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1676 if (_mesa_is_stencil_format(format)) {
1677 /* Drawing stencil */
1680 if (!drawpix->StencilFP)
1681 init_draw_stencil_pixels(ctx);
1683 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1684 GL_ALPHA, type, pixels);
1686 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1688 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1690 /* set all stencil bits to 0 */
1691 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1692 _mesa_StencilFunc(GL_ALWAYS, 0, 255);
1693 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1695 /* set stencil bits to 1 where needed */
1696 _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1698 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1699 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1701 for (bit = 0; bit < ctx->Visual.stencilBits; bit++) {
1702 const GLuint mask = 1 << bit;
1703 if (mask & origStencilMask) {
1704 _mesa_StencilFunc(GL_ALWAYS, mask, mask);
1705 _mesa_StencilMask(mask);
1707 _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1708 255.0 / mask, 0.5, 0.0, 0.0);
1710 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1714 else if (_mesa_is_depth_format(format)) {
1716 if (!drawpix->DepthFP)
1717 init_draw_depth_pixels(ctx);
1719 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1720 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1722 /* polygon color = current raster color */
1723 _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1724 ctx->Current.RasterColor);
1726 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1727 format, type, pixels);
1729 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1733 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1734 format, type, pixels);
1735 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1738 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1740 /* restore unpack params */
1741 ctx->Unpack = unpackSave;
1743 _mesa_meta_end(ctx);
1748 * Do glBitmap with a alpha texture quad. Use the alpha test to
1749 * cull the 'off' bits. If alpha test is already enabled, fall back
1750 * to swrast (should be a rare case).
1751 * A bitmap cache as in the gallium/mesa state tracker would
1752 * improve performance a lot.
1755 _mesa_meta_bitmap(GLcontext *ctx,
1756 GLint x, GLint y, GLsizei width, GLsizei height,
1757 const struct gl_pixelstore_attrib *unpack,
1758 const GLubyte *bitmap1)
1760 struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
1761 struct temp_texture *tex = get_bitmap_temp_texture(ctx);
1762 const GLenum texIntFormat = GL_ALPHA;
1763 const struct gl_pixelstore_attrib unpackSave = *unpack;
1765 GLfloat x, y, z, s, t, r, g, b, a;
1767 struct vertex verts[4];
1772 * Check if swrast fallback is needed.
1774 if (ctx->_ImageTransferState ||
1775 ctx->Color.AlphaEnabled ||
1777 ctx->Texture._EnabledUnits ||
1778 width > tex->MaxSize ||
1779 height > tex->MaxSize) {
1780 _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
1784 /* Most GL state applies to glBitmap (like blending, stencil, etc),
1785 * but a there's a few things we need to override:
1787 _mesa_meta_begin(ctx, (META_ALPHA_TEST |
1789 META_RASTERIZATION |
1796 if (bitmap->ArrayObj == 0) {
1797 /* one-time setup */
1799 /* create vertex array object */
1800 _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
1801 _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
1803 /* create vertex array buffer */
1804 _mesa_GenBuffersARB(1, &bitmap->VBO);
1805 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1806 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1807 NULL, GL_DYNAMIC_DRAW_ARB);
1809 /* setup vertex arrays */
1810 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1811 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1812 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1813 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1814 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1815 _mesa_EnableClientState(GL_COLOR_ARRAY);
1818 _mesa_BindVertexArray(bitmap->ArrayObj);
1819 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1822 newTex = alloc_texture(tex, width, height, texIntFormat);
1824 /* vertex positions, texcoords, colors (after texture allocation!) */
1826 const GLfloat x0 = (GLfloat) x;
1827 const GLfloat y0 = (GLfloat) y;
1828 const GLfloat x1 = (GLfloat) (x + width);
1829 const GLfloat y1 = (GLfloat) (y + height);
1830 const GLfloat z = ctx->Current.RasterPos[2];
1841 verts[1].s = tex->Sright;
1846 verts[2].s = tex->Sright;
1847 verts[2].t = tex->Ttop;
1852 verts[3].t = tex->Ttop;
1854 for (i = 0; i < 4; i++) {
1855 verts[i].r = ctx->Current.RasterColor[0];
1856 verts[i].g = ctx->Current.RasterColor[1];
1857 verts[i].b = ctx->Current.RasterColor[2];
1858 verts[i].a = ctx->Current.RasterColor[3];
1861 /* upload new vertex data */
1862 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1865 bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
1869 bitmap8 = (GLubyte *) _mesa_calloc(width * height);
1871 _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
1872 bitmap8, width, 0xff);
1874 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1876 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
1877 _mesa_AlphaFunc(GL_GREATER, 0.0);
1879 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1880 GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
1882 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1884 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1886 _mesa_free(bitmap8);
1889 _mesa_unmap_pbo_source(ctx, &unpackSave);
1891 _mesa_meta_end(ctx);
1896 _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
1897 struct gl_texture_object *texObj)
1899 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
1901 GLfloat x, y, s, t, r;
1903 struct vertex verts[4];
1904 const GLuint baseLevel = texObj->BaseLevel;
1905 const GLuint maxLevel = texObj->MaxLevel;
1906 const GLenum minFilterSave = texObj->MinFilter;
1907 const GLenum magFilterSave = texObj->MagFilter;
1908 const GLuint fboSave = ctx->DrawBuffer->Name;
1913 /* check for fallbacks */
1914 if (!ctx->Extensions.EXT_framebuffer_object) {
1915 _mesa_generate_mipmap(ctx, target, texObj);
1919 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
1920 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
1921 faceTarget = target;
1922 target = GL_TEXTURE_CUBE_MAP;
1925 faceTarget = target;
1928 _mesa_meta_begin(ctx, META_ALL);
1930 if (mipmap->ArrayObj == 0) {
1931 /* one-time setup */
1933 /* create vertex array object */
1934 _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
1935 _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
1937 /* create vertex array buffer */
1938 _mesa_GenBuffersARB(1, &mipmap->VBO);
1939 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
1940 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1941 NULL, GL_DYNAMIC_DRAW_ARB);
1943 /* setup vertex arrays */
1944 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1945 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1946 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1947 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1950 _mesa_BindVertexArray(mipmap->ArrayObj);
1951 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
1955 /* Bind the new renderbuffer to the color attachment point. */
1956 _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
1959 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
1961 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1962 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1963 _mesa_set_enable(ctx, target, GL_TRUE);
1965 /* setup texcoords once (XXX what about border?) */
1966 switch (faceTarget) {
1967 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1986 for (level = baseLevel + 1; level <= maxLevel; level++) {
1987 const struct gl_texture_image *srcImage;
1988 const GLuint srcLevel = level - 1;
1989 GLsizei srcWidth, srcHeight;
1990 GLsizei newWidth, newHeight;
1993 srcImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
1994 assert(srcImage->Border == 0); /* XXX we can fix this */
1996 srcWidth = srcImage->Width - 2 * border;
1997 srcHeight = srcImage->Height - 2 * border;
1999 newWidth = MAX2(1, srcWidth / 2) + 2 * border;
2000 newHeight = MAX2(1, srcHeight / 2) + 2 * border;
2002 if (newWidth == srcImage->Width && newHeight == srcImage->Height) {
2006 /* Create empty image */
2007 _mesa_TexImage2D(GL_TEXTURE_2D, level, srcImage->InternalFormat,
2008 newWidth, newHeight, border,
2009 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2011 /* vertex positions */
2015 verts[1].x = (GLfloat) newWidth;
2017 verts[2].x = (GLfloat) newWidth;
2018 verts[2].y = (GLfloat) newHeight;
2020 verts[3].y = (GLfloat) newHeight;
2022 /* upload new vertex data */
2023 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2026 /* limit sampling to src level */
2027 _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, srcLevel);
2028 _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, srcLevel);
2030 /* Set to draw into the current level */
2031 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2032 GL_COLOR_ATTACHMENT0_EXT,
2037 /* Choose to render to the color attachment. */
2038 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
2040 status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
2041 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2046 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2049 _mesa_meta_end(ctx);
2051 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
2052 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
2054 /* restore (XXX add to meta_begin/end()? */
2055 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2059 #if FEATURE_OES_draw_texture
2063 * Meta implementation of ctx->Driver.DrawTex() in terms
2064 * of polygon rendering.
2067 _mesa_meta_draw_tex(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z,
2068 GLfloat width, GLfloat height)
2070 struct drawtex_state *drawtex = &ctx->Meta->DrawTex;
2072 GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2];
2074 struct vertex verts[4];
2077 _mesa_meta_begin(ctx, (META_RASTERIZATION |
2083 if (drawtex->ArrayObj == 0) {
2084 /* one-time setup */
2085 GLint active_texture;
2087 /* create vertex array object */
2088 _mesa_GenVertexArrays(1, &drawtex->ArrayObj);
2089 _mesa_BindVertexArray(drawtex->ArrayObj);
2091 /* create vertex array buffer */
2092 _mesa_GenBuffersARB(1, &drawtex->VBO);
2093 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
2094 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2095 NULL, GL_DYNAMIC_DRAW_ARB);
2097 /* client active texture is not part of the array object */
2098 active_texture = ctx->Array.ActiveTexture;
2100 /* setup vertex arrays */
2101 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2102 _mesa_EnableClientState(GL_VERTEX_ARRAY);
2103 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
2104 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i);
2105 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i]));
2106 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2109 /* restore client active texture */
2110 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture);
2113 _mesa_BindVertexArray(drawtex->ArrayObj);
2114 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO);
2117 /* vertex positions, texcoords */
2119 const GLfloat x1 = x + width;
2120 const GLfloat y1 = y + height;
2138 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
2139 const struct gl_texture_object *texObj;
2140 const struct gl_texture_image *texImage;
2141 GLfloat s, t, s1, t1;
2144 if (!ctx->Texture.Unit[i]._ReallyEnabled) {
2146 for (j = 0; j < 4; j++) {
2147 verts[j].st[i][0] = 0.0f;
2148 verts[j].st[i][1] = 0.0f;
2153 texObj = ctx->Texture.Unit[i]._Current;
2154 texImage = texObj->Image[0][texObj->BaseLevel];
2155 tw = texImage->Width2;
2156 th = texImage->Height2;
2158 s = (GLfloat) texObj->CropRect[0] / tw;
2159 t = (GLfloat) texObj->CropRect[1] / th;
2160 s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw;
2161 t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th;
2163 verts[0].st[i][0] = s;
2164 verts[0].st[i][1] = t;
2166 verts[1].st[i][0] = s1;
2167 verts[1].st[i][1] = t;
2169 verts[2].st[i][0] = s1;
2170 verts[2].st[i][1] = t1;
2172 verts[3].st[i][0] = s;
2173 verts[3].st[i][1] = t1;
2176 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2179 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2181 _mesa_meta_end(ctx);
2185 #endif /* FEATURE_OES_draw_texture */