Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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/depth.h"
  44. #include "main/enable.h"
  45. #include "main/fbobject.h"
  46. #include "main/formats.h"
  47. #include "main/image.h"
  48. #include "main/macros.h"
  49. #include "main/matrix.h"
  50. #include "main/mipmap.h"
  51. #include "main/polygon.h"
  52. #include "main/readpix.h"
  53. #include "main/scissor.h"
  54. #include "main/shaderapi.h"
  55. #include "main/shaderobj.h"
  56. #include "main/state.h"
  57. #include "main/stencil.h"
  58. #include "main/texobj.h"
  59. #include "main/texenv.h"
  60. #include "main/teximage.h"
  61. #include "main/texparam.h"
  62. #include "main/texstate.h"
  63. #include "main/varray.h"
  64. #include "main/viewport.h"
  65. #include "program/program.h"
  66. #include "swrast/swrast.h"
  67. #include "drivers/common/meta.h"
  68.  
  69.  
  70. /** Return offset in bytes of the field within a vertex struct */
  71. #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
  72.  
  73.  
  74. /**
  75.  * Flags passed to _mesa_meta_begin().
  76.  */
  77. /*@{*/
  78. #define META_ALL              ~0x0
  79. #define META_ALPHA_TEST        0x1
  80. #define META_BLEND             0x2  /**< includes logicop */
  81. #define META_COLOR_MASK        0x4
  82. #define META_DEPTH_TEST        0x8
  83. #define META_FOG              0x10
  84. #define META_PIXEL_STORE      0x20
  85. #define META_PIXEL_TRANSFER   0x40
  86. #define META_RASTERIZATION    0x80
  87. #define META_SCISSOR         0x100
  88. #define META_SHADER          0x200
  89. #define META_STENCIL_TEST    0x400
  90. #define META_TRANSFORM       0x800 /**< modelview, projection, clip planes */
  91. #define META_TEXTURE        0x1000
  92. #define META_VERTEX         0x2000
  93. #define META_VIEWPORT       0x4000
  94. /*@}*/
  95.  
  96.  
  97. /**
  98.  * State which we may save/restore across meta ops.
  99.  * XXX this may be incomplete...
  100.  */
  101. struct save_state
  102. {
  103.    GLbitfield SavedState;  /**< bitmask of META_* flags */
  104.  
  105.    /** META_ALPHA_TEST */
  106.    GLboolean AlphaEnabled;
  107.    GLenum AlphaFunc;
  108.    GLclampf AlphaRef;
  109.  
  110.    /** META_BLEND */
  111.    GLbitfield BlendEnabled;
  112.    GLboolean ColorLogicOpEnabled;
  113.  
  114.    /** META_COLOR_MASK */
  115.    GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
  116.  
  117.    /** META_DEPTH_TEST */
  118.    struct gl_depthbuffer_attrib Depth;
  119.  
  120.    /** META_FOG */
  121.    GLboolean Fog;
  122.  
  123.    /** META_PIXEL_STORE */
  124.    struct gl_pixelstore_attrib Pack, Unpack;
  125.  
  126.    /** META_PIXEL_TRANSFER */
  127.    GLfloat RedBias, RedScale;
  128.    GLfloat GreenBias, GreenScale;
  129.    GLfloat BlueBias, BlueScale;
  130.    GLfloat AlphaBias, AlphaScale;
  131.    GLfloat DepthBias, DepthScale;
  132.    GLboolean MapColorFlag;
  133.  
  134.    /** META_RASTERIZATION */
  135.    GLenum FrontPolygonMode, BackPolygonMode;
  136.    GLboolean PolygonOffset;
  137.    GLboolean PolygonSmooth;
  138.    GLboolean PolygonStipple;
  139.    GLboolean PolygonCull;
  140.  
  141.    /** META_SCISSOR */
  142.    struct gl_scissor_attrib Scissor;
  143.  
  144.    /** META_SHADER */
  145.    GLboolean VertexProgramEnabled;
  146.    struct gl_vertex_program *VertexProgram;
  147.    GLboolean FragmentProgramEnabled;
  148.    struct gl_fragment_program *FragmentProgram;
  149.    struct gl_shader_program *VertexShader;
  150.    struct gl_shader_program *GeometryShader;
  151.    struct gl_shader_program *FragmentShader;
  152.    struct gl_shader_program *ActiveShader;
  153.  
  154.    /** META_STENCIL_TEST */
  155.    struct gl_stencil_attrib Stencil;
  156.  
  157.    /** META_TRANSFORM */
  158.    GLenum MatrixMode;
  159.    GLfloat ModelviewMatrix[16];
  160.    GLfloat ProjectionMatrix[16];
  161.    GLfloat TextureMatrix[16];
  162.    GLbitfield ClipPlanesEnabled;
  163.  
  164.    /** META_TEXTURE */
  165.    GLuint ActiveUnit;
  166.    GLuint ClientActiveUnit;
  167.    /** for unit[0] only */
  168.    struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
  169.    /** mask of TEXTURE_2D_BIT, etc */
  170.    GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
  171.    GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
  172.    GLuint EnvMode;  /* unit[0] only */
  173.  
  174.    /** META_VERTEX */
  175.    struct gl_array_object *ArrayObj;
  176.    struct gl_buffer_object *ArrayBufferObj;
  177.  
  178.    /** META_VIEWPORT */
  179.    GLint ViewportX, ViewportY, ViewportW, ViewportH;
  180.    GLclampd DepthNear, DepthFar;
  181.  
  182.    /** Miscellaneous (always disabled) */
  183.    GLboolean Lighting;
  184. };
  185.  
  186.  
  187. /**
  188.  * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
  189.  * This is currently shared by all the meta ops.  But we could create a
  190.  * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
  191.  */
  192. struct temp_texture
  193. {
  194.    GLuint TexObj;
  195.    GLenum Target;         /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
  196.    GLsizei MinSize;       /**< Min texture size to allocate */
  197.    GLsizei MaxSize;       /**< Max possible texture size */
  198.    GLboolean NPOT;        /**< Non-power of two size OK? */
  199.    GLsizei Width, Height; /**< Current texture size */
  200.    GLenum IntFormat;
  201.    GLfloat Sright, Ttop;  /**< right, top texcoords */
  202. };
  203.  
  204.  
  205. /**
  206.  * State for glBlitFramebufer()
  207.  */
  208. struct blit_state
  209. {
  210.    GLuint ArrayObj;
  211.    GLuint VBO;
  212.    GLuint DepthFP;
  213. };
  214.  
  215.  
  216. /**
  217.  * State for glClear()
  218.  */
  219. struct clear_state
  220. {
  221.    GLuint ArrayObj;
  222.    GLuint VBO;
  223. };
  224.  
  225.  
  226. /**
  227.  * State for glCopyPixels()
  228.  */
  229. struct copypix_state
  230. {
  231.    GLuint ArrayObj;
  232.    GLuint VBO;
  233. };
  234.  
  235.  
  236. /**
  237.  * State for glDrawPixels()
  238.  */
  239. struct drawpix_state
  240. {
  241.    GLuint ArrayObj;
  242.  
  243.    GLuint StencilFP;  /**< Fragment program for drawing stencil images */
  244.    GLuint DepthFP;  /**< Fragment program for drawing depth images */
  245. };
  246.  
  247.  
  248. /**
  249.  * State for glBitmap()
  250.  */
  251. struct bitmap_state
  252. {
  253.    GLuint ArrayObj;
  254.    GLuint VBO;
  255.    struct temp_texture Tex;  /**< separate texture from other meta ops */
  256. };
  257.  
  258.  
  259. /**
  260.  * State for _mesa_meta_generate_mipmap()
  261.  */
  262. struct gen_mipmap_state
  263. {
  264.    GLuint ArrayObj;
  265.    GLuint VBO;
  266.    GLuint FBO;
  267. };
  268.  
  269. #define MAX_META_OPS_DEPTH      2
  270. /**
  271.  * All per-context meta state.
  272.  */
  273. struct gl_meta_state
  274. {
  275.    /** Stack of state saved during meta-ops */
  276.    struct save_state Save[MAX_META_OPS_DEPTH];
  277.    /** Save stack depth */
  278.    GLuint SaveStackDepth;
  279.  
  280.    struct temp_texture TempTex;
  281.  
  282.    struct blit_state Blit;    /**< For _mesa_meta_BlitFramebuffer() */
  283.    struct clear_state Clear;  /**< For _mesa_meta_Clear() */
  284.    struct copypix_state CopyPix;  /**< For _mesa_meta_CopyPixels() */
  285.    struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
  286.    struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
  287.    struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
  288. };
  289.  
  290.  
  291. /**
  292.  * Initialize meta-ops for a context.
  293.  * To be called once during context creation.
  294.  */
  295. void
  296. _mesa_meta_init(struct gl_context *ctx)
  297. {
  298.    ASSERT(!ctx->Meta);
  299.  
  300.    ctx->Meta = CALLOC_STRUCT(gl_meta_state);
  301. }
  302.  
  303.  
  304. /**
  305.  * Free context meta-op state.
  306.  * To be called once during context destruction.
  307.  */
  308. void
  309. _mesa_meta_free(struct gl_context *ctx)
  310. {
  311.    /* Note: Any textures, VBOs, etc, that we allocate should get
  312.     * freed by the normal context destruction code.  But this would be
  313.     * the place to free other meta data someday.
  314.     */
  315.    free(ctx->Meta);
  316.    ctx->Meta = NULL;
  317. }
  318.  
  319.  
  320. /**
  321.  * Enter meta state.  This is like a light-weight version of glPushAttrib
  322.  * but it also resets most GL state back to default values.
  323.  *
  324.  * \param state  bitmask of META_* flags indicating which attribute groups
  325.  *               to save and reset to their defaults
  326.  */
  327. static void
  328. _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
  329. {
  330.    struct save_state *save;
  331.  
  332.    /* hope MAX_META_OPS_DEPTH is large enough */
  333.    assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);
  334.  
  335.    save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
  336.    memset(save, 0, sizeof(*save));
  337.    save->SavedState = state;
  338.  
  339.    if (state & META_ALPHA_TEST) {
  340.       save->AlphaEnabled = ctx->Color.AlphaEnabled;
  341.       save->AlphaFunc = ctx->Color.AlphaFunc;
  342.       save->AlphaRef = ctx->Color.AlphaRef;
  343.       if (ctx->Color.AlphaEnabled)
  344.          _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
  345.    }
  346.  
  347.    if (state & META_BLEND) {
  348.       save->BlendEnabled = ctx->Color.BlendEnabled;
  349.       if (ctx->Color.BlendEnabled) {
  350.          if (ctx->Extensions.EXT_draw_buffers2) {
  351.             GLuint i;
  352.             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
  353.                _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
  354.             }
  355.          }
  356.          else {
  357.             _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
  358.          }
  359.       }
  360.       save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
  361.       if (ctx->Color.ColorLogicOpEnabled)
  362.          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
  363.    }
  364.  
  365.    if (state & META_COLOR_MASK) {
  366.       memcpy(save->ColorMask, ctx->Color.ColorMask,
  367.              sizeof(ctx->Color.ColorMask));
  368.       if (!ctx->Color.ColorMask[0][0] ||
  369.           !ctx->Color.ColorMask[0][1] ||
  370.           !ctx->Color.ColorMask[0][2] ||
  371.           !ctx->Color.ColorMask[0][3])
  372.          _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  373.    }
  374.  
  375.    if (state & META_DEPTH_TEST) {
  376.       save->Depth = ctx->Depth; /* struct copy */
  377.       if (ctx->Depth.Test)
  378.          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
  379.    }
  380.  
  381.    if (state & META_FOG) {
  382.       save->Fog = ctx->Fog.Enabled;
  383.       if (ctx->Fog.Enabled)
  384.          _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
  385.    }
  386.  
  387.    if (state & META_PIXEL_STORE) {
  388.       save->Pack = ctx->Pack;
  389.       save->Unpack = ctx->Unpack;
  390.       ctx->Pack = ctx->DefaultPacking;
  391.       ctx->Unpack = ctx->DefaultPacking;
  392.    }
  393.  
  394.    if (state & META_PIXEL_TRANSFER) {
  395.       save->RedScale = ctx->Pixel.RedScale;
  396.       save->RedBias = ctx->Pixel.RedBias;
  397.       save->GreenScale = ctx->Pixel.GreenScale;
  398.       save->GreenBias = ctx->Pixel.GreenBias;
  399.       save->BlueScale = ctx->Pixel.BlueScale;
  400.       save->BlueBias = ctx->Pixel.BlueBias;
  401.       save->AlphaScale = ctx->Pixel.AlphaScale;
  402.       save->AlphaBias = ctx->Pixel.AlphaBias;
  403.       save->MapColorFlag = ctx->Pixel.MapColorFlag;
  404.       ctx->Pixel.RedScale = 1.0F;
  405.       ctx->Pixel.RedBias = 0.0F;
  406.       ctx->Pixel.GreenScale = 1.0F;
  407.       ctx->Pixel.GreenBias = 0.0F;
  408.       ctx->Pixel.BlueScale = 1.0F;
  409.       ctx->Pixel.BlueBias = 0.0F;
  410.       ctx->Pixel.AlphaScale = 1.0F;
  411.       ctx->Pixel.AlphaBias = 0.0F;
  412.       ctx->Pixel.MapColorFlag = GL_FALSE;
  413.       /* XXX more state */
  414.       ctx->NewState |=_NEW_PIXEL;
  415.    }
  416.  
  417.    if (state & META_RASTERIZATION) {
  418.       save->FrontPolygonMode = ctx->Polygon.FrontMode;
  419.       save->BackPolygonMode = ctx->Polygon.BackMode;
  420.       save->PolygonOffset = ctx->Polygon.OffsetFill;
  421.       save->PolygonSmooth = ctx->Polygon.SmoothFlag;
  422.       save->PolygonStipple = ctx->Polygon.StippleFlag;
  423.       save->PolygonCull = ctx->Polygon.CullFlag;
  424.       _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  425.       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
  426.       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
  427.       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
  428.       _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
  429.    }
  430.  
  431.    if (state & META_SCISSOR) {
  432.       save->Scissor = ctx->Scissor; /* struct copy */
  433.       _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE);
  434.    }
  435.  
  436.    if (state & META_SHADER) {
  437.       if (ctx->Extensions.ARB_vertex_program) {
  438.          save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
  439.          _mesa_reference_vertprog(ctx, &save->VertexProgram,
  440.                                   ctx->VertexProgram.Current);
  441.          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
  442.       }
  443.  
  444.       if (ctx->Extensions.ARB_fragment_program) {
  445.          save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
  446.          _mesa_reference_fragprog(ctx, &save->FragmentProgram,
  447.                                   ctx->FragmentProgram.Current);
  448.          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
  449.       }
  450.  
  451.       if (ctx->Extensions.ARB_shader_objects) {
  452.          _mesa_reference_shader_program(ctx, &save->VertexShader,
  453.                                         ctx->Shader.CurrentVertexProgram);
  454.          _mesa_reference_shader_program(ctx, &save->GeometryShader,
  455.                                         ctx->Shader.CurrentGeometryProgram);
  456.          _mesa_reference_shader_program(ctx, &save->FragmentShader,
  457.                                         ctx->Shader.CurrentFragmentProgram);
  458.          _mesa_reference_shader_program(ctx, &save->ActiveShader,
  459.                                         ctx->Shader.CurrentFragmentProgram);
  460.  
  461.          _mesa_UseProgramObjectARB(0);
  462.       }
  463.    }
  464.  
  465.    if (state & META_STENCIL_TEST) {
  466.       save->Stencil = ctx->Stencil; /* struct copy */
  467.       if (ctx->Stencil.Enabled)
  468.          _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
  469.       /* NOTE: other stencil state not reset */
  470.    }
  471.  
  472.    if (state & META_TEXTURE) {
  473.       GLuint u, tgt;
  474.  
  475.       save->ActiveUnit = ctx->Texture.CurrentUnit;
  476.       save->ClientActiveUnit = ctx->Array.ActiveTexture;
  477.       save->EnvMode = ctx->Texture.Unit[0].EnvMode;
  478.  
  479.       /* Disable all texture units */
  480.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  481.          save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
  482.          save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
  483.          if (ctx->Texture.Unit[u].Enabled ||
  484.              ctx->Texture.Unit[u].TexGenEnabled) {
  485.             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
  486.             _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
  487.             _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
  488.             _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
  489.             if (ctx->Extensions.ARB_texture_cube_map)
  490.                _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
  491.             _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
  492.             _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
  493.             _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
  494.             _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
  495.             _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
  496.          }
  497.       }
  498.  
  499.       /* save current texture objects for unit[0] only */
  500.       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
  501.          _mesa_reference_texobj(&save->CurrentTexture[tgt],
  502.                                 ctx->Texture.Unit[0].CurrentTex[tgt]);
  503.       }
  504.  
  505.       /* set defaults for unit[0] */
  506.       _mesa_ActiveTextureARB(GL_TEXTURE0);
  507.       _mesa_ClientActiveTextureARB(GL_TEXTURE0);
  508.       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  509.    }
  510.  
  511.    if (state & META_TRANSFORM) {
  512.       GLuint activeTexture = ctx->Texture.CurrentUnit;
  513.       memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
  514.              16 * sizeof(GLfloat));
  515.       memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
  516.              16 * sizeof(GLfloat));
  517.       memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
  518.              16 * sizeof(GLfloat));
  519.       save->MatrixMode = ctx->Transform.MatrixMode;
  520.       /* set 1:1 vertex:pixel coordinate transform */
  521.       _mesa_ActiveTextureARB(GL_TEXTURE0);
  522.       _mesa_MatrixMode(GL_TEXTURE);
  523.       _mesa_LoadIdentity();
  524.       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
  525.       _mesa_MatrixMode(GL_MODELVIEW);
  526.       _mesa_LoadIdentity();
  527.       _mesa_MatrixMode(GL_PROJECTION);
  528.       _mesa_LoadIdentity();
  529.       _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
  530.                   0.0, ctx->DrawBuffer->Height,
  531.                   -1.0, 1.0);
  532.       save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
  533.       if (ctx->Transform.ClipPlanesEnabled) {
  534.          GLuint i;
  535.          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
  536.             _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
  537.          }
  538.       }
  539.    }
  540.  
  541.    if (state & META_VERTEX) {
  542.       /* save vertex array object state */
  543.       _mesa_reference_array_object(ctx, &save->ArrayObj,
  544.                                    ctx->Array.ArrayObj);
  545.       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
  546.                                     ctx->Array.ArrayBufferObj);
  547.       /* set some default state? */
  548.    }
  549.  
  550.    if (state & META_VIEWPORT) {
  551.       /* save viewport state */
  552.       save->ViewportX = ctx->Viewport.X;
  553.       save->ViewportY = ctx->Viewport.Y;
  554.       save->ViewportW = ctx->Viewport.Width;
  555.       save->ViewportH = ctx->Viewport.Height;
  556.       /* set viewport to match window size */
  557.       if (ctx->Viewport.X != 0 ||
  558.           ctx->Viewport.Y != 0 ||
  559.           ctx->Viewport.Width != ctx->DrawBuffer->Width ||
  560.           ctx->Viewport.Height != ctx->DrawBuffer->Height) {
  561.          _mesa_set_viewport(ctx, 0, 0,
  562.                             ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
  563.       }
  564.       /* save depth range state */
  565.       save->DepthNear = ctx->Viewport.Near;
  566.       save->DepthFar = ctx->Viewport.Far;
  567.       /* set depth range to default */
  568.       _mesa_DepthRange(0.0, 1.0);
  569.    }
  570.  
  571.    /* misc */
  572.    {
  573.       save->Lighting = ctx->Light.Enabled;
  574.       if (ctx->Light.Enabled)
  575.          _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
  576.    }
  577. }
  578.  
  579.  
  580. /**
  581.  * Leave meta state.  This is like a light-weight version of glPopAttrib().
  582.  */
  583. static void
  584. _mesa_meta_end(struct gl_context *ctx)
  585. {
  586.    struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth];
  587.    const GLbitfield state = save->SavedState;
  588.  
  589.    if (state & META_ALPHA_TEST) {
  590.       if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
  591.          _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
  592.       _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
  593.    }
  594.  
  595.    if (state & META_BLEND) {
  596.       if (ctx->Color.BlendEnabled != save->BlendEnabled) {
  597.          if (ctx->Extensions.EXT_draw_buffers2) {
  598.             GLuint i;
  599.             for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
  600.                _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
  601.             }
  602.          }
  603.          else {
  604.             _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
  605.          }
  606.       }
  607.       if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
  608.          _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
  609.    }
  610.  
  611.    if (state & META_COLOR_MASK) {
  612.       GLuint i;
  613.       for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
  614.          if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
  615.             if (i == 0) {
  616.                _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
  617.                                save->ColorMask[i][2], save->ColorMask[i][3]);
  618.             }
  619.             else {
  620.                _mesa_ColorMaskIndexed(i,
  621.                                       save->ColorMask[i][0],
  622.                                       save->ColorMask[i][1],
  623.                                       save->ColorMask[i][2],
  624.                                       save->ColorMask[i][3]);
  625.             }
  626.          }
  627.       }
  628.    }
  629.  
  630.    if (state & META_DEPTH_TEST) {
  631.       if (ctx->Depth.Test != save->Depth.Test)
  632.          _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
  633.       _mesa_DepthFunc(save->Depth.Func);
  634.       _mesa_DepthMask(save->Depth.Mask);
  635.    }
  636.  
  637.    if (state & META_FOG) {
  638.       _mesa_set_enable(ctx, GL_FOG, save->Fog);
  639.    }
  640.  
  641.    if (state & META_PIXEL_STORE) {
  642.       ctx->Pack = save->Pack;
  643.       ctx->Unpack = save->Unpack;
  644.    }
  645.  
  646.    if (state & META_PIXEL_TRANSFER) {
  647.       ctx->Pixel.RedScale = save->RedScale;
  648.       ctx->Pixel.RedBias = save->RedBias;
  649.       ctx->Pixel.GreenScale = save->GreenScale;
  650.       ctx->Pixel.GreenBias = save->GreenBias;
  651.       ctx->Pixel.BlueScale = save->BlueScale;
  652.       ctx->Pixel.BlueBias = save->BlueBias;
  653.       ctx->Pixel.AlphaScale = save->AlphaScale;
  654.       ctx->Pixel.AlphaBias = save->AlphaBias;
  655.       ctx->Pixel.MapColorFlag = save->MapColorFlag;
  656.       /* XXX more state */
  657.       ctx->NewState |=_NEW_PIXEL;
  658.    }
  659.  
  660.    if (state & META_RASTERIZATION) {
  661.       _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
  662.       _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
  663.       _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
  664.       _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
  665.       _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
  666.       _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
  667.    }
  668.  
  669.    if (state & META_SCISSOR) {
  670.       _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
  671.       _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
  672.                     save->Scissor.Width, save->Scissor.Height);
  673.    }
  674.  
  675.    if (state & META_SHADER) {
  676.       if (ctx->Extensions.ARB_vertex_program) {
  677.          _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
  678.                           save->VertexProgramEnabled);
  679.          _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
  680.                                   save->VertexProgram);
  681.          _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL);
  682.       }
  683.  
  684.       if (ctx->Extensions.ARB_fragment_program) {
  685.          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
  686.                           save->FragmentProgramEnabled);
  687.          _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
  688.                                   save->FragmentProgram);
  689.          _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
  690.       }
  691.  
  692.       if (ctx->Extensions.ARB_vertex_shader)
  693.          _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
  694.  
  695.       if (ctx->Extensions.ARB_geometry_shader4)
  696.          _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
  697.                                   save->GeometryShader);
  698.  
  699.       if (ctx->Extensions.ARB_fragment_shader)
  700.          _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
  701.                                   save->FragmentShader);
  702.  
  703.       _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram,
  704.                                      save->ActiveShader);
  705.    }
  706.  
  707.    if (state & META_STENCIL_TEST) {
  708.       const struct gl_stencil_attrib *stencil = &save->Stencil;
  709.  
  710.       _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
  711.       _mesa_ClearStencil(stencil->Clear);
  712.       if (ctx->Extensions.EXT_stencil_two_side) {
  713.          _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
  714.                           stencil->TestTwoSide);
  715.          _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
  716.                                     ? GL_BACK : GL_FRONT);
  717.       }
  718.       /* front state */
  719.       _mesa_StencilFuncSeparate(GL_FRONT,
  720.                                 stencil->Function[0],
  721.                                 stencil->Ref[0],
  722.                                 stencil->ValueMask[0]);
  723.       _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
  724.       _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
  725.                               stencil->ZFailFunc[0],
  726.                               stencil->ZPassFunc[0]);
  727.       /* back state */
  728.       _mesa_StencilFuncSeparate(GL_BACK,
  729.                                 stencil->Function[1],
  730.                                 stencil->Ref[1],
  731.                                 stencil->ValueMask[1]);
  732.       _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
  733.       _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
  734.                               stencil->ZFailFunc[1],
  735.                               stencil->ZPassFunc[1]);
  736.    }
  737.  
  738.    if (state & META_TEXTURE) {
  739.       GLuint u, tgt;
  740.  
  741.       ASSERT(ctx->Texture.CurrentUnit == 0);
  742.  
  743.       /* restore texenv for unit[0] */
  744.       _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
  745.  
  746.       /* restore texture objects for unit[0] only */
  747.       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
  748.          _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
  749.                                 save->CurrentTexture[tgt]);
  750.          _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
  751.       }
  752.  
  753.       /* Re-enable textures, texgen */
  754.       for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
  755.          if (save->TexEnabled[u]) {
  756.             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
  757.  
  758.             if (save->TexEnabled[u] & TEXTURE_1D_BIT)
  759.                _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
  760.             if (save->TexEnabled[u] & TEXTURE_2D_BIT)
  761.                _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
  762.             if (save->TexEnabled[u] & TEXTURE_3D_BIT)
  763.                _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
  764.             if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
  765.                _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
  766.             if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
  767.                _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
  768.          }
  769.  
  770.          if (save->TexGenEnabled[u]) {
  771.             _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
  772.  
  773.             if (save->TexGenEnabled[u] & S_BIT)
  774.                _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
  775.             if (save->TexGenEnabled[u] & T_BIT)
  776.                _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
  777.             if (save->TexGenEnabled[u] & R_BIT)
  778.                _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
  779.             if (save->TexGenEnabled[u] & Q_BIT)
  780.                _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
  781.          }
  782.       }
  783.  
  784.       /* restore current unit state */
  785.       _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
  786.       _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
  787.    }
  788.  
  789.    if (state & META_TRANSFORM) {
  790.       GLuint activeTexture = ctx->Texture.CurrentUnit;
  791.       _mesa_ActiveTextureARB(GL_TEXTURE0);
  792.       _mesa_MatrixMode(GL_TEXTURE);
  793.       _mesa_LoadMatrixf(save->TextureMatrix);
  794.       _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
  795.  
  796.       _mesa_MatrixMode(GL_MODELVIEW);
  797.       _mesa_LoadMatrixf(save->ModelviewMatrix);
  798.  
  799.       _mesa_MatrixMode(GL_PROJECTION);
  800.       _mesa_LoadMatrixf(save->ProjectionMatrix);
  801.  
  802.       _mesa_MatrixMode(save->MatrixMode);
  803.  
  804.       if (save->ClipPlanesEnabled) {
  805.          GLuint i;
  806.          for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
  807.             if (save->ClipPlanesEnabled & (1 << i)) {
  808.                _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
  809.             }
  810.          }
  811.       }
  812.    }
  813.  
  814.    if (state & META_VERTEX) {
  815.       /* restore vertex buffer object */
  816.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
  817.       _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
  818.  
  819.       /* restore vertex array object */
  820.       _mesa_BindVertexArray(save->ArrayObj->Name);
  821.       _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
  822.    }
  823.  
  824.    if (state & META_VIEWPORT) {
  825.       if (save->ViewportX != ctx->Viewport.X ||
  826.           save->ViewportY != ctx->Viewport.Y ||
  827.           save->ViewportW != ctx->Viewport.Width ||
  828.           save->ViewportH != ctx->Viewport.Height) {
  829.          _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
  830.                             save->ViewportW, save->ViewportH);
  831.       }
  832.       _mesa_DepthRange(save->DepthNear, save->DepthFar);
  833.    }
  834.  
  835.    /* misc */
  836.    if (save->Lighting) {
  837.       _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
  838.    }
  839. }
  840.  
  841.  
  842. /**
  843.  * Convert Z from a normalized value in the range [0, 1] to an object-space
  844.  * Z coordinate in [-1, +1] so that drawing at the new Z position with the
  845.  * default/identity ortho projection results in the original Z value.
  846.  * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z
  847.  * value comes from the clear value or raster position.
  848.  */
  849. static INLINE GLfloat
  850. invert_z(GLfloat normZ)
  851. {
  852.    GLfloat objZ = 1.0 - 2.0 * normZ;
  853.    return objZ;
  854. }
  855.  
  856.  
  857. /**
  858.  * One-time init for a temp_texture object.
  859.  * Choose tex target, compute max tex size, etc.
  860.  */
  861. static void
  862. init_temp_texture(struct gl_context *ctx, struct temp_texture *tex)
  863. {
  864.    /* prefer texture rectangle */
  865.    if (ctx->Extensions.NV_texture_rectangle) {
  866.       tex->Target = GL_TEXTURE_RECTANGLE;
  867.       tex->MaxSize = ctx->Const.MaxTextureRectSize;
  868.       tex->NPOT = GL_TRUE;
  869.    }
  870.    else {
  871.       /* use 2D texture, NPOT if possible */
  872.       tex->Target = GL_TEXTURE_2D;
  873.       tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
  874.       tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
  875.    }
  876.    tex->MinSize = 16;  /* 16 x 16 at least */
  877.    assert(tex->MaxSize > 0);
  878.  
  879.    _mesa_GenTextures(1, &tex->TexObj);
  880. }
  881.  
  882.  
  883. /**
  884.  * Return pointer to temp_texture info for non-bitmap ops.
  885.  * This does some one-time init if needed.
  886.  */
  887. static struct temp_texture *
  888. get_temp_texture(struct gl_context *ctx)
  889. {
  890.    struct temp_texture *tex = &ctx->Meta->TempTex;
  891.  
  892.    if (!tex->TexObj) {
  893.       init_temp_texture(ctx, tex);
  894.    }
  895.  
  896.    return tex;
  897. }
  898.  
  899.  
  900. /**
  901.  * Return pointer to temp_texture info for _mesa_meta_bitmap().
  902.  * We use a separate texture for bitmaps to reduce texture
  903.  * allocation/deallocation.
  904.  */
  905. static struct temp_texture *
  906. get_bitmap_temp_texture(struct gl_context *ctx)
  907. {
  908.    struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
  909.  
  910.    if (!tex->TexObj) {
  911.       init_temp_texture(ctx, tex);
  912.    }
  913.  
  914.    return tex;
  915. }
  916.  
  917.  
  918. /**
  919.  * Compute the width/height of texture needed to draw an image of the
  920.  * given size.  Return a flag indicating whether the current texture
  921.  * can be re-used (glTexSubImage2D) or if a new texture needs to be
  922.  * allocated (glTexImage2D).
  923.  * Also, compute s/t texcoords for drawing.
  924.  *
  925.  * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
  926.  */
  927. static GLboolean
  928. alloc_texture(struct temp_texture *tex,
  929.               GLsizei width, GLsizei height, GLenum intFormat)
  930. {
  931.    GLboolean newTex = GL_FALSE;
  932.  
  933.    ASSERT(width <= tex->MaxSize);
  934.    ASSERT(height <= tex->MaxSize);
  935.  
  936.    if (width > tex->Width ||
  937.        height > tex->Height ||
  938.        intFormat != tex->IntFormat) {
  939.       /* alloc new texture (larger or different format) */
  940.  
  941.       if (tex->NPOT) {
  942.          /* use non-power of two size */
  943.          tex->Width = MAX2(tex->MinSize, width);
  944.          tex->Height = MAX2(tex->MinSize, height);
  945.       }
  946.       else {
  947.          /* find power of two size */
  948.          GLsizei w, h;
  949.          w = h = tex->MinSize;
  950.          while (w < width)
  951.             w *= 2;
  952.          while (h < height)
  953.             h *= 2;
  954.          tex->Width = w;
  955.          tex->Height = h;
  956.       }
  957.  
  958.       tex->IntFormat = intFormat;
  959.  
  960.       newTex = GL_TRUE;
  961.    }
  962.  
  963.    /* compute texcoords */
  964.    if (tex->Target == GL_TEXTURE_RECTANGLE) {
  965.       tex->Sright = (GLfloat) width;
  966.       tex->Ttop = (GLfloat) height;
  967.    }
  968.    else {
  969.       tex->Sright = (GLfloat) width / tex->Width;
  970.       tex->Ttop = (GLfloat) height / tex->Height;
  971.    }
  972.  
  973.    return newTex;
  974. }
  975.  
  976.  
  977. /**
  978.  * Setup/load texture for glCopyPixels or glBlitFramebuffer.
  979.  */
  980. static void
  981. setup_copypix_texture(struct temp_texture *tex,
  982.                       GLboolean newTex,
  983.                       GLint srcX, GLint srcY,
  984.                       GLsizei width, GLsizei height, GLenum intFormat,
  985.                       GLenum filter)
  986. {
  987.    _mesa_BindTexture(tex->Target, tex->TexObj);
  988.    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
  989.    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
  990.    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  991.  
  992.    /* copy framebuffer image to texture */
  993.    if (newTex) {
  994.       /* create new tex image */
  995.       if (tex->Width == width && tex->Height == height) {
  996.          /* create new tex with framebuffer data */
  997.          _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
  998.                               srcX, srcY, width, height, 0);
  999.       }
  1000.       else {
  1001.          /* create empty texture */
  1002.          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
  1003.                           tex->Width, tex->Height, 0,
  1004.                           intFormat, GL_UNSIGNED_BYTE, NULL);
  1005.          /* load image */
  1006.          _mesa_CopyTexSubImage2D(tex->Target, 0,
  1007.                                  0, 0, srcX, srcY, width, height);
  1008.       }
  1009.    }
  1010.    else {
  1011.       /* replace existing tex image */
  1012.       _mesa_CopyTexSubImage2D(tex->Target, 0,
  1013.                               0, 0, srcX, srcY, width, height);
  1014.    }
  1015. }
  1016.  
  1017.  
  1018. /**
  1019.  * Setup/load texture for glDrawPixels.
  1020.  */
  1021. static void
  1022. setup_drawpix_texture(struct gl_context *ctx,
  1023.                       struct temp_texture *tex,
  1024.                       GLboolean newTex,
  1025.                       GLenum texIntFormat,
  1026.                       GLsizei width, GLsizei height,
  1027.                       GLenum format, GLenum type,
  1028.                       const GLvoid *pixels)
  1029. {
  1030.    _mesa_BindTexture(tex->Target, tex->TexObj);
  1031.    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  1032.    _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  1033.    _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1034.  
  1035.    /* copy pixel data to texture */
  1036.    if (newTex) {
  1037.       /* create new tex image */
  1038.       if (tex->Width == width && tex->Height == height) {
  1039.          /* create new tex and load image data */
  1040.          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
  1041.                           tex->Width, tex->Height, 0, format, type, pixels);
  1042.       }
  1043.       else {
  1044.          struct gl_buffer_object *save_unpack_obj = NULL;
  1045.  
  1046.          _mesa_reference_buffer_object(ctx, &save_unpack_obj,
  1047.                                        ctx->Unpack.BufferObj);
  1048.          _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
  1049.          /* create empty texture */
  1050.          _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
  1051.                           tex->Width, tex->Height, 0, format, type, NULL);
  1052.          if (save_unpack_obj != NULL)
  1053.             _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
  1054.                                 save_unpack_obj->Name);
  1055.          /* load image */
  1056.          _mesa_TexSubImage2D(tex->Target, 0,
  1057.                              0, 0, width, height, format, type, pixels);
  1058.       }
  1059.    }
  1060.    else {
  1061.       /* replace existing tex image */
  1062.       _mesa_TexSubImage2D(tex->Target, 0,
  1063.                           0, 0, width, height, format, type, pixels);
  1064.    }
  1065. }
  1066.  
  1067.  
  1068.  
  1069. /**
  1070.  * One-time init for drawing depth pixels.
  1071.  */
  1072. static void
  1073. init_blit_depth_pixels(struct gl_context *ctx)
  1074. {
  1075.    static const char *program =
  1076.       "!!ARBfp1.0\n"
  1077.       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
  1078.       "END \n";
  1079.    char program2[200];
  1080.    struct blit_state *blit = &ctx->Meta->Blit;
  1081.    struct temp_texture *tex = get_temp_texture(ctx);
  1082.    const char *texTarget;
  1083.  
  1084.    assert(blit->DepthFP == 0);
  1085.  
  1086.    /* replace %s with "RECT" or "2D" */
  1087.    assert(strlen(program) + 4 < sizeof(program2));
  1088.    if (tex->Target == GL_TEXTURE_RECTANGLE)
  1089.       texTarget = "RECT";
  1090.    else
  1091.       texTarget = "2D";
  1092.    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
  1093.  
  1094.    _mesa_GenPrograms(1, &blit->DepthFP);
  1095.    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
  1096.    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
  1097.                           strlen(program2), (const GLubyte *) program2);
  1098. }
  1099.  
  1100.  
  1101. /**
  1102.  * Try to do a glBlitFramebuffer using no-copy texturing.
  1103.  * We can do this when the src renderbuffer is actually a texture.
  1104.  * But if the src buffer == dst buffer we cannot do this.
  1105.  *
  1106.  * \return new buffer mask indicating the buffers left to blit using the
  1107.  *         normal path.
  1108.  */
  1109. static GLbitfield
  1110. blitframebuffer_texture(struct gl_context *ctx,
  1111.                         GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  1112.                         GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  1113.                         GLbitfield mask, GLenum filter)
  1114. {
  1115.    if (mask & GL_COLOR_BUFFER_BIT) {
  1116.       const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
  1117.       const struct gl_framebuffer *readFb = ctx->ReadBuffer;
  1118.       const struct gl_renderbuffer_attachment *drawAtt =
  1119.          &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
  1120.       const struct gl_renderbuffer_attachment *readAtt =
  1121.          &readFb->Attachment[readFb->_ColorReadBufferIndex];
  1122.  
  1123.       if (readAtt && readAtt->Texture) {
  1124.          const struct gl_texture_object *texObj = readAtt->Texture;
  1125.          const GLuint srcLevel = readAtt->TextureLevel;
  1126.          const GLenum minFilterSave = texObj->MinFilter;
  1127.          const GLenum magFilterSave = texObj->MagFilter;
  1128.          const GLint baseLevelSave = texObj->BaseLevel;
  1129.          const GLint maxLevelSave = texObj->MaxLevel;
  1130.          const GLenum wrapSSave = texObj->WrapS;
  1131.          const GLenum wrapTSave = texObj->WrapT;
  1132.          const GLenum target = texObj->Target;
  1133.  
  1134.          if (drawAtt->Texture == readAtt->Texture) {
  1135.             /* Can't use same texture as both the source and dest.  We need
  1136.              * to handle overlapping blits and besides, some hw may not
  1137.              * support this.
  1138.              */
  1139.             return mask;
  1140.          }
  1141.  
  1142.          if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
  1143.             /* Can't handle other texture types at this time */
  1144.             return mask;
  1145.          }
  1146.  
  1147.          /*
  1148.          printf("Blit from texture!\n");
  1149.          printf("  srcAtt %p  dstAtt %p\n", readAtt, drawAtt);
  1150.          printf("  srcTex %p  dstText %p\n", texObj, drawAtt->Texture);
  1151.          */
  1152.  
  1153.          /* Prepare src texture state */
  1154.          _mesa_BindTexture(target, texObj->Name);
  1155.          _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
  1156.          _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
  1157.          if (target != GL_TEXTURE_RECTANGLE_ARB) {
  1158.             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
  1159.             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
  1160.          }
  1161.          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1162.          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1163.          _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1164.          _mesa_set_enable(ctx, target, GL_TRUE);
  1165.  
  1166.          /* Prepare vertex data (the VBO was previously created and bound) */
  1167.          {
  1168.             struct vertex {
  1169.                GLfloat x, y, s, t;
  1170.             };
  1171.             struct vertex verts[4];
  1172.             GLfloat s0, t0, s1, t1;
  1173.  
  1174.             if (target == GL_TEXTURE_2D) {
  1175.                const struct gl_texture_image *texImage
  1176.                    = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
  1177.                s0 = srcX0 / (float) texImage->Width;
  1178.                s1 = srcX1 / (float) texImage->Width;
  1179.                t0 = srcY0 / (float) texImage->Height;
  1180.                t1 = srcY1 / (float) texImage->Height;
  1181.             }
  1182.             else {
  1183.                assert(target == GL_TEXTURE_RECTANGLE_ARB);
  1184.                s0 = srcX0;
  1185.                s1 = srcX1;
  1186.                t0 = srcY0;
  1187.                t1 = srcY1;
  1188.             }
  1189.  
  1190.             verts[0].x = (GLfloat) dstX0;
  1191.             verts[0].y = (GLfloat) dstY0;
  1192.             verts[1].x = (GLfloat) dstX1;
  1193.             verts[1].y = (GLfloat) dstY0;
  1194.             verts[2].x = (GLfloat) dstX1;
  1195.             verts[2].y = (GLfloat) dstY1;
  1196.             verts[3].x = (GLfloat) dstX0;
  1197.             verts[3].y = (GLfloat) dstY1;
  1198.  
  1199.             verts[0].s = s0;
  1200.             verts[0].t = t0;
  1201.             verts[1].s = s1;
  1202.             verts[1].t = t0;
  1203.             verts[2].s = s1;
  1204.             verts[2].t = t1;
  1205.             verts[3].s = s0;
  1206.             verts[3].t = t1;
  1207.  
  1208.             _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
  1209.          }
  1210.  
  1211.          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1212.  
  1213.          /* Restore texture object state, the texture binding will
  1214.           * be restored by _mesa_meta_end().
  1215.           */
  1216.          _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
  1217.          _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
  1218.          if (target != GL_TEXTURE_RECTANGLE_ARB) {
  1219.             _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
  1220.             _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
  1221.          }
  1222.          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
  1223.          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
  1224.  
  1225.          /* Done with color buffer */
  1226.          mask &= ~GL_COLOR_BUFFER_BIT;
  1227.       }
  1228.    }
  1229.  
  1230.    return mask;
  1231. }
  1232.  
  1233.  
  1234. /**
  1235.  * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
  1236.  * of texture mapping and polygon rendering.
  1237.  */
  1238. void
  1239. _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
  1240.                            GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
  1241.                            GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
  1242.                            GLbitfield mask, GLenum filter)
  1243. {
  1244.    struct blit_state *blit = &ctx->Meta->Blit;
  1245.    struct temp_texture *tex = get_temp_texture(ctx);
  1246.    const GLsizei maxTexSize = tex->MaxSize;
  1247.    const GLint srcX = MIN2(srcX0, srcX1);
  1248.    const GLint srcY = MIN2(srcY0, srcY1);
  1249.    const GLint srcW = abs(srcX1 - srcX0);
  1250.    const GLint srcH = abs(srcY1 - srcY0);
  1251.    const GLboolean srcFlipX = srcX1 < srcX0;
  1252.    const GLboolean srcFlipY = srcY1 < srcY0;
  1253.    struct vertex {
  1254.       GLfloat x, y, s, t;
  1255.    };
  1256.    struct vertex verts[4];
  1257.    GLboolean newTex;
  1258.  
  1259.    if (srcW > maxTexSize || srcH > maxTexSize) {
  1260.       /* XXX avoid this fallback */
  1261.       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
  1262.                               dstX0, dstY0, dstX1, dstY1, mask, filter);
  1263.       return;
  1264.    }
  1265.  
  1266.    if (srcFlipX) {
  1267.       GLint tmp = dstX0;
  1268.       dstX0 = dstX1;
  1269.       dstX1 = tmp;
  1270.    }
  1271.  
  1272.    if (srcFlipY) {
  1273.       GLint tmp = dstY0;
  1274.       dstY0 = dstY1;
  1275.       dstY1 = tmp;
  1276.    }
  1277.  
  1278.    /* only scissor effects blit so save/clear all other relevant state */
  1279.    _mesa_meta_begin(ctx, ~META_SCISSOR);
  1280.  
  1281.    if (blit->ArrayObj == 0) {
  1282.       /* one-time setup */
  1283.  
  1284.       /* create vertex array object */
  1285.       _mesa_GenVertexArrays(1, &blit->ArrayObj);
  1286.       _mesa_BindVertexArray(blit->ArrayObj);
  1287.  
  1288.       /* create vertex array buffer */
  1289.       _mesa_GenBuffersARB(1, &blit->VBO);
  1290.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
  1291.       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
  1292.                           NULL, GL_DYNAMIC_DRAW_ARB);
  1293.  
  1294.       /* setup vertex arrays */
  1295.       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  1296.       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
  1297.       _mesa_EnableClientState(GL_VERTEX_ARRAY);
  1298.       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
  1299.    }
  1300.    else {
  1301.       _mesa_BindVertexArray(blit->ArrayObj);
  1302.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
  1303.    }
  1304.  
  1305.    /* Try faster, direct texture approach first */
  1306.    mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
  1307.                                   dstX0, dstY0, dstX1, dstY1, mask, filter);
  1308.    if (mask == 0x0) {
  1309.       _mesa_meta_end(ctx);
  1310.       return;
  1311.    }
  1312.  
  1313.    /* Continue with "normal" approach which involves copying the src rect
  1314.     * into a temporary texture and is "blitted" by drawing a textured quad.
  1315.     */
  1316.  
  1317.    newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
  1318.  
  1319.    /* vertex positions/texcoords (after texture allocation!) */
  1320.    {
  1321.       verts[0].x = (GLfloat) dstX0;
  1322.       verts[0].y = (GLfloat) dstY0;
  1323.       verts[1].x = (GLfloat) dstX1;
  1324.       verts[1].y = (GLfloat) dstY0;
  1325.       verts[2].x = (GLfloat) dstX1;
  1326.       verts[2].y = (GLfloat) dstY1;
  1327.       verts[3].x = (GLfloat) dstX0;
  1328.       verts[3].y = (GLfloat) dstY1;
  1329.  
  1330.       verts[0].s = 0.0F;
  1331.       verts[0].t = 0.0F;
  1332.       verts[1].s = tex->Sright;
  1333.       verts[1].t = 0.0F;
  1334.       verts[2].s = tex->Sright;
  1335.       verts[2].t = tex->Ttop;
  1336.       verts[3].s = 0.0F;
  1337.       verts[3].t = tex->Ttop;
  1338.  
  1339.       /* upload new vertex data */
  1340.       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
  1341.    }
  1342.  
  1343.    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
  1344.  
  1345.    if (mask & GL_COLOR_BUFFER_BIT) {
  1346.       setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
  1347.                             GL_RGBA, filter);
  1348.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1349.       mask &= ~GL_COLOR_BUFFER_BIT;
  1350.    }
  1351.  
  1352.    if (mask & GL_DEPTH_BUFFER_BIT) {
  1353.       GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
  1354.       if (tmp) {
  1355.          if (!blit->DepthFP)
  1356.             init_blit_depth_pixels(ctx);
  1357.  
  1358.          /* maybe change tex format here */
  1359.          newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
  1360.  
  1361.          _mesa_ReadPixels(srcX, srcY, srcW, srcH,
  1362.                           GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
  1363.  
  1364.          setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
  1365.                                GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
  1366.  
  1367.          _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
  1368.          _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
  1369.          _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1370.          _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
  1371.          _mesa_DepthFunc(GL_ALWAYS);
  1372.          _mesa_DepthMask(GL_TRUE);
  1373.  
  1374.          _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1375.          mask &= ~GL_DEPTH_BUFFER_BIT;
  1376.  
  1377.          free(tmp);
  1378.       }
  1379.    }
  1380.  
  1381.    if (mask & GL_STENCIL_BUFFER_BIT) {
  1382.       /* XXX can't easily do stencil */
  1383.    }
  1384.  
  1385.    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
  1386.  
  1387.    _mesa_meta_end(ctx);
  1388.  
  1389.    if (mask) {
  1390.       _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
  1391.                               dstX0, dstY0, dstX1, dstY1, mask, filter);
  1392.    }
  1393. }
  1394.  
  1395.  
  1396. /**
  1397.  * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
  1398.  */
  1399. void
  1400. _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
  1401. {
  1402.    struct clear_state *clear = &ctx->Meta->Clear;
  1403.    struct vertex {
  1404.       GLfloat x, y, z, r, g, b, a;
  1405.    };
  1406.    struct vertex verts[4];
  1407.    /* save all state but scissor, pixel pack/unpack */
  1408.    GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
  1409.    const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
  1410.  
  1411.    if (buffers & BUFFER_BITS_COLOR) {
  1412.       /* if clearing color buffers, don't save/restore colormask */
  1413.       metaSave -= META_COLOR_MASK;
  1414.    }
  1415.  
  1416.    _mesa_meta_begin(ctx, metaSave);
  1417.  
  1418.    if (clear->ArrayObj == 0) {
  1419.       /* one-time setup */
  1420.  
  1421.       /* create vertex array object */
  1422.       _mesa_GenVertexArrays(1, &clear->ArrayObj);
  1423.       _mesa_BindVertexArray(clear->ArrayObj);
  1424.  
  1425.       /* create vertex array buffer */
  1426.       _mesa_GenBuffersARB(1, &clear->VBO);
  1427.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
  1428.  
  1429.       /* setup vertex arrays */
  1430.       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  1431.       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
  1432.       _mesa_EnableClientState(GL_VERTEX_ARRAY);
  1433.       _mesa_EnableClientState(GL_COLOR_ARRAY);
  1434.    }
  1435.    else {
  1436.       _mesa_BindVertexArray(clear->ArrayObj);
  1437.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
  1438.    }
  1439.  
  1440.    /* GL_COLOR_BUFFER_BIT */
  1441.    if (buffers & BUFFER_BITS_COLOR) {
  1442.       /* leave colormask, glDrawBuffer state as-is */
  1443.    }
  1444.    else {
  1445.       ASSERT(metaSave & META_COLOR_MASK);
  1446.       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1447.    }
  1448.  
  1449.    /* GL_DEPTH_BUFFER_BIT */
  1450.    if (buffers & BUFFER_BIT_DEPTH) {
  1451.       _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
  1452.       _mesa_DepthFunc(GL_ALWAYS);
  1453.       _mesa_DepthMask(GL_TRUE);
  1454.    }
  1455.    else {
  1456.       assert(!ctx->Depth.Test);
  1457.    }
  1458.  
  1459.    /* GL_STENCIL_BUFFER_BIT */
  1460.    if (buffers & BUFFER_BIT_STENCIL) {
  1461.       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
  1462.       _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
  1463.                               GL_REPLACE, GL_REPLACE, GL_REPLACE);
  1464.       _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
  1465.                                 ctx->Stencil.Clear & stencilMax,
  1466.                                 ctx->Stencil.WriteMask[0]);
  1467.    }
  1468.    else {
  1469.       assert(!ctx->Stencil.Enabled);
  1470.    }
  1471.  
  1472.    /* vertex positions/colors */
  1473.    {
  1474.       const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
  1475.       const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
  1476.       const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
  1477.       const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
  1478.       const GLfloat z = invert_z(ctx->Depth.Clear);
  1479.       GLuint i;
  1480.  
  1481.       verts[0].x = x0;
  1482.       verts[0].y = y0;
  1483.       verts[0].z = z;
  1484.       verts[1].x = x1;
  1485.       verts[1].y = y0;
  1486.       verts[1].z = z;
  1487.       verts[2].x = x1;
  1488.       verts[2].y = y1;
  1489.       verts[2].z = z;
  1490.       verts[3].x = x0;
  1491.       verts[3].y = y1;
  1492.       verts[3].z = z;
  1493.  
  1494.       /* vertex colors */
  1495.       for (i = 0; i < 4; i++) {
  1496.          verts[i].r = ctx->Color.ClearColor[0];
  1497.          verts[i].g = ctx->Color.ClearColor[1];
  1498.          verts[i].b = ctx->Color.ClearColor[2];
  1499.          verts[i].a = ctx->Color.ClearColor[3];
  1500.       }
  1501.  
  1502.       /* upload new vertex data */
  1503.       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
  1504.                           GL_DYNAMIC_DRAW_ARB);
  1505.    }
  1506.  
  1507.    /* draw quad */
  1508.    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1509.  
  1510.    _mesa_meta_end(ctx);
  1511. }
  1512.  
  1513.  
  1514. /**
  1515.  * Meta implementation of ctx->Driver.CopyPixels() in terms
  1516.  * of texture mapping and polygon rendering.
  1517.  */
  1518. void
  1519. _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
  1520.                       GLsizei width, GLsizei height,
  1521.                       GLint dstX, GLint dstY, GLenum type)
  1522. {
  1523.    struct copypix_state *copypix = &ctx->Meta->CopyPix;
  1524.    struct temp_texture *tex = get_temp_texture(ctx);
  1525.    struct vertex {
  1526.       GLfloat x, y, z, s, t;
  1527.    };
  1528.    struct vertex verts[4];
  1529.    GLboolean newTex;
  1530.    GLenum intFormat = GL_RGBA;
  1531.  
  1532.    if (type != GL_COLOR ||
  1533.        ctx->_ImageTransferState ||
  1534.        ctx->Fog.Enabled ||
  1535.        width > tex->MaxSize ||
  1536.        height > tex->MaxSize) {
  1537.       /* XXX avoid this fallback */
  1538.       _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
  1539.       return;
  1540.    }
  1541.  
  1542.    /* Most GL state applies to glCopyPixels, but a there's a few things
  1543.     * we need to override:
  1544.     */
  1545.    _mesa_meta_begin(ctx, (META_RASTERIZATION |
  1546.                           META_SHADER |
  1547.                           META_TEXTURE |
  1548.                           META_TRANSFORM |
  1549.                           META_VERTEX |
  1550.                           META_VIEWPORT));
  1551.  
  1552.    if (copypix->ArrayObj == 0) {
  1553.       /* one-time setup */
  1554.  
  1555.       /* create vertex array object */
  1556.       _mesa_GenVertexArrays(1, &copypix->ArrayObj);
  1557.       _mesa_BindVertexArray(copypix->ArrayObj);
  1558.  
  1559.       /* create vertex array buffer */
  1560.       _mesa_GenBuffersARB(1, &copypix->VBO);
  1561.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
  1562.       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
  1563.                           NULL, GL_DYNAMIC_DRAW_ARB);
  1564.  
  1565.       /* setup vertex arrays */
  1566.       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  1567.       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
  1568.       _mesa_EnableClientState(GL_VERTEX_ARRAY);
  1569.       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
  1570.    }
  1571.    else {
  1572.       _mesa_BindVertexArray(copypix->ArrayObj);
  1573.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
  1574.    }
  1575.  
  1576.    newTex = alloc_texture(tex, width, height, intFormat);
  1577.  
  1578.    /* vertex positions, texcoords (after texture allocation!) */
  1579.    {
  1580.       const GLfloat dstX0 = (GLfloat) dstX;
  1581.       const GLfloat dstY0 = (GLfloat) dstY;
  1582.       const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
  1583.       const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
  1584.       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
  1585.  
  1586.       verts[0].x = dstX0;
  1587.       verts[0].y = dstY0;
  1588.       verts[0].z = z;
  1589.       verts[0].s = 0.0F;
  1590.       verts[0].t = 0.0F;
  1591.       verts[1].x = dstX1;
  1592.       verts[1].y = dstY0;
  1593.       verts[1].z = z;
  1594.       verts[1].s = tex->Sright;
  1595.       verts[1].t = 0.0F;
  1596.       verts[2].x = dstX1;
  1597.       verts[2].y = dstY1;
  1598.       verts[2].z = z;
  1599.       verts[2].s = tex->Sright;
  1600.       verts[2].t = tex->Ttop;
  1601.       verts[3].x = dstX0;
  1602.       verts[3].y = dstY1;
  1603.       verts[3].z = z;
  1604.       verts[3].s = 0.0F;
  1605.       verts[3].t = tex->Ttop;
  1606.  
  1607.       /* upload new vertex data */
  1608.       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
  1609.    }
  1610.  
  1611.    /* Alloc/setup texture */
  1612.    setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
  1613.                          GL_RGBA, GL_NEAREST);
  1614.  
  1615.    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
  1616.  
  1617.    /* draw textured quad */
  1618.    _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1619.  
  1620.    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
  1621.  
  1622.    _mesa_meta_end(ctx);
  1623. }
  1624.  
  1625.  
  1626.  
  1627. /**
  1628.  * When the glDrawPixels() image size is greater than the max rectangle
  1629.  * texture size we use this function to break the glDrawPixels() image
  1630.  * into tiles which fit into the max texture size.
  1631.  */
  1632. static void
  1633. tiled_draw_pixels(struct gl_context *ctx,
  1634.                   GLint tileSize,
  1635.                   GLint x, GLint y, GLsizei width, GLsizei height,
  1636.                   GLenum format, GLenum type,
  1637.                   const struct gl_pixelstore_attrib *unpack,
  1638.                   const GLvoid *pixels)
  1639. {
  1640.    struct gl_pixelstore_attrib tileUnpack = *unpack;
  1641.    GLint i, j;
  1642.  
  1643.    if (tileUnpack.RowLength == 0)
  1644.       tileUnpack.RowLength = width;
  1645.  
  1646.    for (i = 0; i < width; i += tileSize) {
  1647.       const GLint tileWidth = MIN2(tileSize, width - i);
  1648.       const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
  1649.  
  1650.       tileUnpack.SkipPixels = unpack->SkipPixels + i;
  1651.  
  1652.       for (j = 0; j < height; j += tileSize) {
  1653.          const GLint tileHeight = MIN2(tileSize, height - j);
  1654.          const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
  1655.  
  1656.          tileUnpack.SkipRows = unpack->SkipRows + j;
  1657.  
  1658.          _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
  1659.                                format, type, &tileUnpack, pixels);
  1660.       }
  1661.    }
  1662. }
  1663.  
  1664.  
  1665. /**
  1666.  * One-time init for drawing stencil pixels.
  1667.  */
  1668. static void
  1669. init_draw_stencil_pixels(struct gl_context *ctx)
  1670. {
  1671.    /* This program is run eight times, once for each stencil bit.
  1672.     * The stencil values to draw are found in an 8-bit alpha texture.
  1673.     * We read the texture/stencil value and test if bit 'b' is set.
  1674.     * If the bit is not set, use KIL to kill the fragment.
  1675.     * Finally, we use the stencil test to update the stencil buffer.
  1676.     *
  1677.     * The basic algorithm for checking if a bit is set is:
  1678.     *   if (is_odd(value / (1 << bit)))
  1679.     *      result is one (or non-zero).
  1680.     *   else
  1681.     *      result is zero.
  1682.     * The program parameter contains three values:
  1683.     *   parm.x = 255 / (1 << bit)
  1684.     *   parm.y = 0.5
  1685.     *   parm.z = 0.0
  1686.     */
  1687.    static const char *program =
  1688.       "!!ARBfp1.0\n"
  1689.       "PARAM parm = program.local[0]; \n"
  1690.       "TEMP t; \n"
  1691.       "TEX t, fragment.texcoord[0], texture[0], %s; \n"   /* NOTE %s here! */
  1692.       "# t = t * 255 / bit \n"
  1693.       "MUL t.x, t.a, parm.x; \n"
  1694.       "# t = (int) t \n"
  1695.       "FRC t.y, t.x; \n"
  1696.       "SUB t.x, t.x, t.y; \n"
  1697.       "# t = t * 0.5 \n"
  1698.       "MUL t.x, t.x, parm.y; \n"
  1699.       "# t = fract(t.x) \n"
  1700.       "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
  1701.       "# t.x = (t.x == 0 ? 1 : 0) \n"
  1702.       "SGE t.x, -t.x, parm.z; \n"
  1703.       "KIL -t.x; \n"
  1704.       "# for debug only \n"
  1705.       "#MOV result.color, t.x; \n"
  1706.       "END \n";
  1707.    char program2[1000];
  1708.    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
  1709.    struct temp_texture *tex = get_temp_texture(ctx);
  1710.    const char *texTarget;
  1711.  
  1712.    assert(drawpix->StencilFP == 0);
  1713.  
  1714.    /* replace %s with "RECT" or "2D" */
  1715.    assert(strlen(program) + 4 < sizeof(program2));
  1716.    if (tex->Target == GL_TEXTURE_RECTANGLE)
  1717.       texTarget = "RECT";
  1718.    else
  1719.       texTarget = "2D";
  1720.    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
  1721.  
  1722.    _mesa_GenPrograms(1, &drawpix->StencilFP);
  1723.    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
  1724.    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
  1725.                           strlen(program2), (const GLubyte *) program2);
  1726. }
  1727.  
  1728.  
  1729. /**
  1730.  * One-time init for drawing depth pixels.
  1731.  */
  1732. static void
  1733. init_draw_depth_pixels(struct gl_context *ctx)
  1734. {
  1735.    static const char *program =
  1736.       "!!ARBfp1.0\n"
  1737.       "PARAM color = program.local[0]; \n"
  1738.       "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
  1739.       "MOV result.color, color; \n"
  1740.       "END \n";
  1741.    char program2[200];
  1742.    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
  1743.    struct temp_texture *tex = get_temp_texture(ctx);
  1744.    const char *texTarget;
  1745.  
  1746.    assert(drawpix->DepthFP == 0);
  1747.  
  1748.    /* replace %s with "RECT" or "2D" */
  1749.    assert(strlen(program) + 4 < sizeof(program2));
  1750.    if (tex->Target == GL_TEXTURE_RECTANGLE)
  1751.       texTarget = "RECT";
  1752.    else
  1753.       texTarget = "2D";
  1754.    _mesa_snprintf(program2, sizeof(program2), program, texTarget);
  1755.  
  1756.    _mesa_GenPrograms(1, &drawpix->DepthFP);
  1757.    _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
  1758.    _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
  1759.                           strlen(program2), (const GLubyte *) program2);
  1760. }
  1761.  
  1762.  
  1763. /**
  1764.  * Meta implementation of ctx->Driver.DrawPixels() in terms
  1765.  * of texture mapping and polygon rendering.
  1766.  */
  1767. void
  1768. _mesa_meta_DrawPixels(struct gl_context *ctx,
  1769.                       GLint x, GLint y, GLsizei width, GLsizei height,
  1770.                       GLenum format, GLenum type,
  1771.                       const struct gl_pixelstore_attrib *unpack,
  1772.                       const GLvoid *pixels)
  1773. {
  1774.    struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
  1775.    struct temp_texture *tex = get_temp_texture(ctx);
  1776.    const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
  1777.    const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
  1778.    struct vertex {
  1779.       GLfloat x, y, z, s, t;
  1780.    };
  1781.    struct vertex verts[4];
  1782.    GLenum texIntFormat;
  1783.    GLboolean fallback, newTex;
  1784.    GLbitfield metaExtraSave = 0x0;
  1785.    GLuint vbo;
  1786.  
  1787.    /*
  1788.     * Determine if we can do the glDrawPixels with texture mapping.
  1789.     */
  1790.    fallback = GL_FALSE;
  1791.    if (ctx->_ImageTransferState ||
  1792.        ctx->Fog.Enabled) {
  1793.       fallback = GL_TRUE;
  1794.    }
  1795.  
  1796.    if (_mesa_is_color_format(format)) {
  1797.       /* use more compact format when possible */
  1798.       /* XXX disable special case for GL_LUMINANCE for now to work around
  1799.        * apparent i965 driver bug (see bug #23670).
  1800.        */
  1801.       if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
  1802.          texIntFormat = format;
  1803.       else
  1804.          texIntFormat = GL_RGBA;
  1805.    }
  1806.    else if (_mesa_is_stencil_format(format)) {
  1807.       if (ctx->Extensions.ARB_fragment_program &&
  1808.           ctx->Pixel.IndexShift == 0 &&
  1809.           ctx->Pixel.IndexOffset == 0 &&
  1810.           type == GL_UNSIGNED_BYTE) {
  1811.          /* We'll store stencil as alpha.  This only works for GLubyte
  1812.           * image data because of how incoming values are mapped to alpha
  1813.           * in [0,1].
  1814.           */
  1815.          texIntFormat = GL_ALPHA;
  1816.          metaExtraSave = (META_COLOR_MASK |
  1817.                           META_DEPTH_TEST |
  1818.                           META_SHADER |
  1819.                           META_STENCIL_TEST);
  1820.       }
  1821.       else {
  1822.          fallback = GL_TRUE;
  1823.       }
  1824.    }
  1825.    else if (_mesa_is_depth_format(format)) {
  1826.       if (ctx->Extensions.ARB_depth_texture &&
  1827.           ctx->Extensions.ARB_fragment_program) {
  1828.          texIntFormat = GL_DEPTH_COMPONENT;
  1829.          metaExtraSave = (META_SHADER);
  1830.       }
  1831.       else {
  1832.          fallback = GL_TRUE;
  1833.       }
  1834.    }
  1835.    else {
  1836.       fallback = GL_TRUE;
  1837.    }
  1838.  
  1839.    if (fallback) {
  1840.       _swrast_DrawPixels(ctx, x, y, width, height,
  1841.                          format, type, unpack, pixels);
  1842.       return;
  1843.    }
  1844.  
  1845.    /*
  1846.     * Check image size against max texture size, draw as tiles if needed.
  1847.     */
  1848.    if (width > tex->MaxSize || height > tex->MaxSize) {
  1849.       tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
  1850.                         format, type, unpack, pixels);
  1851.       return;
  1852.    }
  1853.  
  1854.    /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
  1855.     * but a there's a few things we need to override:
  1856.     */
  1857.    _mesa_meta_begin(ctx, (META_RASTERIZATION |
  1858.                           META_SHADER |
  1859.                           META_TEXTURE |
  1860.                           META_TRANSFORM |
  1861.                           META_VERTEX |
  1862.                           META_VIEWPORT |
  1863.                           metaExtraSave));
  1864.  
  1865.    newTex = alloc_texture(tex, width, height, texIntFormat);
  1866.  
  1867.    /* vertex positions, texcoords (after texture allocation!) */
  1868.    {
  1869.       const GLfloat x0 = (GLfloat) x;
  1870.       const GLfloat y0 = (GLfloat) y;
  1871.       const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
  1872.       const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
  1873.       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
  1874.  
  1875.       verts[0].x = x0;
  1876.       verts[0].y = y0;
  1877.       verts[0].z = z;
  1878.       verts[0].s = 0.0F;
  1879.       verts[0].t = 0.0F;
  1880.       verts[1].x = x1;
  1881.       verts[1].y = y0;
  1882.       verts[1].z = z;
  1883.       verts[1].s = tex->Sright;
  1884.       verts[1].t = 0.0F;
  1885.       verts[2].x = x1;
  1886.       verts[2].y = y1;
  1887.       verts[2].z = z;
  1888.       verts[2].s = tex->Sright;
  1889.       verts[2].t = tex->Ttop;
  1890.       verts[3].x = x0;
  1891.       verts[3].y = y1;
  1892.       verts[3].z = z;
  1893.       verts[3].s = 0.0F;
  1894.       verts[3].t = tex->Ttop;
  1895.    }
  1896.  
  1897.    if (drawpix->ArrayObj == 0) {
  1898.       /* one-time setup: create vertex array object */
  1899.       _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
  1900.    }
  1901.    _mesa_BindVertexArray(drawpix->ArrayObj);
  1902.  
  1903.    /* create vertex array buffer */
  1904.    _mesa_GenBuffersARB(1, &vbo);
  1905.    _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
  1906.    _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
  1907.                        verts, GL_DYNAMIC_DRAW_ARB);
  1908.  
  1909.    /* setup vertex arrays */
  1910.    _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  1911.    _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
  1912.    _mesa_EnableClientState(GL_VERTEX_ARRAY);
  1913.    _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
  1914.  
  1915.    /* set given unpack params */
  1916.    ctx->Unpack = *unpack;
  1917.  
  1918.    _mesa_set_enable(ctx, tex->Target, GL_TRUE);
  1919.  
  1920.    if (_mesa_is_stencil_format(format)) {
  1921.       /* Drawing stencil */
  1922.       GLint bit;
  1923.  
  1924.       if (!drawpix->StencilFP)
  1925.          init_draw_stencil_pixels(ctx);
  1926.  
  1927.       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
  1928.                             GL_ALPHA, type, pixels);
  1929.  
  1930.       _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  1931.  
  1932.       _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
  1933.  
  1934.       /* set all stencil bits to 0 */
  1935.       _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
  1936.       _mesa_StencilFunc(GL_ALWAYS, 0, 255);
  1937.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1938.  
  1939.       /* set stencil bits to 1 where needed */
  1940.       _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
  1941.  
  1942.       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
  1943.       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
  1944.  
  1945.       for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
  1946.          const GLuint mask = 1 << bit;
  1947.          if (mask & origStencilMask) {
  1948.             _mesa_StencilFunc(GL_ALWAYS, mask, mask);
  1949.             _mesa_StencilMask(mask);
  1950.  
  1951.             _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
  1952.                                              255.0 / mask, 0.5, 0.0, 0.0);
  1953.  
  1954.             _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1955.          }
  1956.       }
  1957.    }
  1958.    else if (_mesa_is_depth_format(format)) {
  1959.       /* Drawing depth */
  1960.       if (!drawpix->DepthFP)
  1961.          init_draw_depth_pixels(ctx);
  1962.  
  1963.       _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
  1964.       _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
  1965.  
  1966.       /* polygon color = current raster color */
  1967.       _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
  1968.                                         ctx->Current.RasterColor);
  1969.  
  1970.       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
  1971.                             format, type, pixels);
  1972.  
  1973.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1974.    }
  1975.    else {
  1976.       /* Drawing RGBA */
  1977.       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
  1978.                             format, type, pixels);
  1979.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  1980.    }
  1981.  
  1982.    _mesa_set_enable(ctx, tex->Target, GL_FALSE);
  1983.  
  1984.    _mesa_DeleteBuffersARB(1, &vbo);
  1985.  
  1986.    /* restore unpack params */
  1987.    ctx->Unpack = unpackSave;
  1988.  
  1989.    _mesa_meta_end(ctx);
  1990. }
  1991.  
  1992. static GLboolean
  1993. alpha_test_raster_color(struct gl_context *ctx)
  1994. {
  1995.    GLfloat alpha = ctx->Current.RasterColor[ACOMP];
  1996.    GLfloat ref = ctx->Color.AlphaRef;
  1997.  
  1998.    switch (ctx->Color.AlphaFunc) {
  1999.       case GL_NEVER:
  2000.          return GL_FALSE;
  2001.       case GL_LESS:
  2002.          return alpha < ref;
  2003.       case GL_EQUAL:
  2004.          return alpha == ref;
  2005.       case GL_LEQUAL:
  2006.          return alpha <= ref;
  2007.       case GL_GREATER:
  2008.          return alpha > ref;
  2009.       case GL_NOTEQUAL:
  2010.          return alpha != ref;
  2011.       case GL_GEQUAL:
  2012.          return alpha >= ref;
  2013.       case GL_ALWAYS:
  2014.          return GL_TRUE;
  2015.       default:
  2016.          assert(0);
  2017.          return GL_FALSE;
  2018.    }
  2019. }
  2020.  
  2021. /**
  2022.  * Do glBitmap with a alpha texture quad.  Use the alpha test to cull
  2023.  * the 'off' bits.  A bitmap cache as in the gallium/mesa state
  2024.  * tracker would improve performance a lot.
  2025.  */
  2026. void
  2027. _mesa_meta_Bitmap(struct gl_context *ctx,
  2028.                   GLint x, GLint y, GLsizei width, GLsizei height,
  2029.                   const struct gl_pixelstore_attrib *unpack,
  2030.                   const GLubyte *bitmap1)
  2031. {
  2032.    struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
  2033.    struct temp_texture *tex = get_bitmap_temp_texture(ctx);
  2034.    const GLenum texIntFormat = GL_ALPHA;
  2035.    const struct gl_pixelstore_attrib unpackSave = *unpack;
  2036.    GLubyte fg, bg;
  2037.    struct vertex {
  2038.       GLfloat x, y, z, s, t, r, g, b, a;
  2039.    };
  2040.    struct vertex verts[4];
  2041.    GLboolean newTex;
  2042.    GLubyte *bitmap8;
  2043.  
  2044.    /*
  2045.     * Check if swrast fallback is needed.
  2046.     */
  2047.    if (ctx->_ImageTransferState ||
  2048.        ctx->FragmentProgram._Enabled ||
  2049.        ctx->Fog.Enabled ||
  2050.        ctx->Texture._EnabledUnits ||
  2051.        width > tex->MaxSize ||
  2052.        height > tex->MaxSize) {
  2053.       _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
  2054.       return;
  2055.    }
  2056.  
  2057.    if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
  2058.       return;
  2059.  
  2060.    /* Most GL state applies to glBitmap (like blending, stencil, etc),
  2061.     * but a there's a few things we need to override:
  2062.     */
  2063.    _mesa_meta_begin(ctx, (META_ALPHA_TEST |
  2064.                           META_PIXEL_STORE |
  2065.                           META_RASTERIZATION |
  2066.                           META_SHADER |
  2067.                           META_TEXTURE |
  2068.                           META_TRANSFORM |
  2069.                           META_VERTEX |
  2070.                           META_VIEWPORT));
  2071.  
  2072.    if (bitmap->ArrayObj == 0) {
  2073.       /* one-time setup */
  2074.  
  2075.       /* create vertex array object */
  2076.       _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
  2077.       _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
  2078.  
  2079.       /* create vertex array buffer */
  2080.       _mesa_GenBuffersARB(1, &bitmap->VBO);
  2081.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
  2082.       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
  2083.                           NULL, GL_DYNAMIC_DRAW_ARB);
  2084.  
  2085.       /* setup vertex arrays */
  2086.       _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  2087.       _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
  2088.       _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
  2089.       _mesa_EnableClientState(GL_VERTEX_ARRAY);
  2090.       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
  2091.       _mesa_EnableClientState(GL_COLOR_ARRAY);
  2092.    }
  2093.    else {
  2094.       _mesa_BindVertexArray(bitmap->ArrayObj);
  2095.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
  2096.    }
  2097.  
  2098.    newTex = alloc_texture(tex, width, height, texIntFormat);
  2099.  
  2100.    /* vertex positions, texcoords, colors (after texture allocation!) */
  2101.    {
  2102.       const GLfloat x0 = (GLfloat) x;
  2103.       const GLfloat y0 = (GLfloat) y;
  2104.       const GLfloat x1 = (GLfloat) (x + width);
  2105.       const GLfloat y1 = (GLfloat) (y + height);
  2106.       const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
  2107.       GLuint i;
  2108.  
  2109.       verts[0].x = x0;
  2110.       verts[0].y = y0;
  2111.       verts[0].z = z;
  2112.       verts[0].s = 0.0F;
  2113.       verts[0].t = 0.0F;
  2114.       verts[1].x = x1;
  2115.       verts[1].y = y0;
  2116.       verts[1].z = z;
  2117.       verts[1].s = tex->Sright;
  2118.       verts[1].t = 0.0F;
  2119.       verts[2].x = x1;
  2120.       verts[2].y = y1;
  2121.       verts[2].z = z;
  2122.       verts[2].s = tex->Sright;
  2123.       verts[2].t = tex->Ttop;
  2124.       verts[3].x = x0;
  2125.       verts[3].y = y1;
  2126.       verts[3].z = z;
  2127.       verts[3].s = 0.0F;
  2128.       verts[3].t = tex->Ttop;
  2129.  
  2130.       for (i = 0; i < 4; i++) {
  2131.          verts[i].r = ctx->Current.RasterColor[0];
  2132.          verts[i].g = ctx->Current.RasterColor[1];
  2133.          verts[i].b = ctx->Current.RasterColor[2];
  2134.          verts[i].a = ctx->Current.RasterColor[3];
  2135.       }
  2136.  
  2137.       /* upload new vertex data */
  2138.       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
  2139.    }
  2140.  
  2141.    /* choose different foreground/background alpha values */
  2142.    CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
  2143.    bg = (fg > 127 ? 0 : 255);
  2144.  
  2145.    bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
  2146.    if (!bitmap1) {
  2147.       _mesa_meta_end(ctx);
  2148.       return;
  2149.    }
  2150.  
  2151.    bitmap8 = (GLubyte *) malloc(width * height);
  2152.    if (bitmap8) {
  2153.       memset(bitmap8, bg, width * height);
  2154.       _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
  2155.                           bitmap8, width, fg);
  2156.  
  2157.       _mesa_set_enable(ctx, tex->Target, GL_TRUE);
  2158.  
  2159.       _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
  2160.       _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
  2161.  
  2162.       setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
  2163.                             GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
  2164.  
  2165.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  2166.  
  2167.       _mesa_set_enable(ctx, tex->Target, GL_FALSE);
  2168.  
  2169.       free(bitmap8);
  2170.    }
  2171.  
  2172.    _mesa_unmap_pbo_source(ctx, &unpackSave);
  2173.  
  2174.    _mesa_meta_end(ctx);
  2175. }
  2176.  
  2177.  
  2178. /**
  2179.  * Check if the call to _mesa_meta_GenerateMipmap() will require a
  2180.  * software fallback.  The fallback path will require that the texture
  2181.  * images are mapped.
  2182.  * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
  2183.  */
  2184. GLboolean
  2185. _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
  2186.                                           struct gl_texture_object *texObj)
  2187. {
  2188.    const GLuint fboSave = ctx->DrawBuffer->Name;
  2189.    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
  2190.    struct gl_texture_image *baseImage;
  2191.    GLuint srcLevel;
  2192.    GLenum status;
  2193.  
  2194.    /* check for fallbacks */
  2195.    if (!ctx->Extensions.EXT_framebuffer_object ||
  2196.        target == GL_TEXTURE_3D) {
  2197.       return GL_TRUE;
  2198.    }
  2199.  
  2200.    srcLevel = texObj->BaseLevel;
  2201.    baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
  2202.    if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) {
  2203.       return GL_TRUE;
  2204.    }
  2205.  
  2206.    /*
  2207.     * Test that we can actually render in the texture's format.
  2208.     */
  2209.    if (!mipmap->FBO)
  2210.       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
  2211.    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
  2212.  
  2213.    if (target == GL_TEXTURE_1D) {
  2214.       _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
  2215.                                     GL_COLOR_ATTACHMENT0_EXT,
  2216.                                     target, texObj->Name, srcLevel);
  2217.    }
  2218. #if 0
  2219.    /* other work is needed to enable 3D mipmap generation */
  2220.    else if (target == GL_TEXTURE_3D) {
  2221.       GLint zoffset = 0;
  2222.       _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
  2223.                                     GL_COLOR_ATTACHMENT0_EXT,
  2224.                                     target, texObj->Name, srcLevel, zoffset);
  2225.    }
  2226. #endif
  2227.    else {
  2228.       /* 2D / cube */
  2229.       _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
  2230.                                     GL_COLOR_ATTACHMENT0_EXT,
  2231.                                     target, texObj->Name, srcLevel);
  2232.    }
  2233.  
  2234.    status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  2235.  
  2236.    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
  2237.  
  2238.    if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  2239.       return GL_TRUE;
  2240.    }
  2241.  
  2242.    return GL_FALSE;
  2243. }
  2244.  
  2245.  
  2246. /**
  2247.  * Called via ctx->Driver.GenerateMipmap()
  2248.  * Note: texture borders and 3D texture support not yet complete.
  2249.  */
  2250. void
  2251. _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
  2252.                           struct gl_texture_object *texObj)
  2253. {
  2254.    struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
  2255.    struct vertex {
  2256.       GLfloat x, y, s, t, r;
  2257.    };
  2258.    struct vertex verts[4];
  2259.    const GLuint baseLevel = texObj->BaseLevel;
  2260.    const GLuint maxLevel = texObj->MaxLevel;
  2261.    const GLenum minFilterSave = texObj->MinFilter;
  2262.    const GLenum magFilterSave = texObj->MagFilter;
  2263.    const GLint baseLevelSave = texObj->BaseLevel;
  2264.    const GLint maxLevelSave = texObj->MaxLevel;
  2265.    const GLboolean genMipmapSave = texObj->GenerateMipmap;
  2266.    const GLenum wrapSSave = texObj->WrapS;
  2267.    const GLenum wrapTSave = texObj->WrapT;
  2268.    const GLenum wrapRSave = texObj->WrapR;
  2269.    const GLuint fboSave = ctx->DrawBuffer->Name;
  2270.    const GLuint original_active_unit = ctx->Texture.CurrentUnit;
  2271.    GLenum faceTarget;
  2272.    GLuint dstLevel;
  2273.    GLuint border = 0;
  2274.  
  2275.    if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
  2276.       _mesa_generate_mipmap(ctx, target, texObj);
  2277.       return;
  2278.    }
  2279.  
  2280.    if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  2281.        target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
  2282.       faceTarget = target;
  2283.       target = GL_TEXTURE_CUBE_MAP;
  2284.    }
  2285.    else {
  2286.       faceTarget = target;
  2287.    }
  2288.  
  2289.    _mesa_meta_begin(ctx, META_ALL);
  2290.  
  2291.    if (original_active_unit != 0)
  2292.       _mesa_BindTexture(target, texObj->Name);
  2293.  
  2294.    if (mipmap->ArrayObj == 0) {
  2295.       /* one-time setup */
  2296.  
  2297.       /* create vertex array object */
  2298.       _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
  2299.       _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
  2300.  
  2301.       /* create vertex array buffer */
  2302.       _mesa_GenBuffersARB(1, &mipmap->VBO);
  2303.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
  2304.       _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
  2305.                           NULL, GL_DYNAMIC_DRAW_ARB);
  2306.  
  2307.       /* setup vertex arrays */
  2308.       _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
  2309.       _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
  2310.       _mesa_EnableClientState(GL_VERTEX_ARRAY);
  2311.       _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
  2312.    }
  2313.    else {
  2314.       _mesa_BindVertexArray(mipmap->ArrayObj);
  2315.       _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
  2316.    }
  2317.  
  2318.    if (!mipmap->FBO) {
  2319.       _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
  2320.    }
  2321.    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
  2322.  
  2323.    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  2324.    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  2325.    _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
  2326.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  2327.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  2328.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
  2329.  
  2330.    _mesa_set_enable(ctx, target, GL_TRUE);
  2331.  
  2332.    /* setup texcoords once (XXX what about border?) */
  2333.    switch (faceTarget) {
  2334.    case GL_TEXTURE_1D:
  2335.    case GL_TEXTURE_2D:
  2336.       verts[0].s = 0.0F;
  2337.       verts[0].t = 0.0F;
  2338.       verts[0].r = 0.0F;
  2339.       verts[1].s = 1.0F;
  2340.       verts[1].t = 0.0F;
  2341.       verts[1].r = 0.0F;
  2342.       verts[2].s = 1.0F;
  2343.       verts[2].t = 1.0F;
  2344.       verts[2].r = 0.0F;
  2345.       verts[3].s = 0.0F;
  2346.       verts[3].t = 1.0F;
  2347.       verts[3].r = 0.0F;
  2348.       break;
  2349.    case GL_TEXTURE_3D:
  2350.       abort();
  2351.       break;
  2352.    default:
  2353.       /* cube face */
  2354.       {
  2355.          static const GLfloat st[4][2] = {
  2356.             {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
  2357.          };
  2358.          GLuint i;
  2359.  
  2360.          /* loop over quad verts */
  2361.          for (i = 0; i < 4; i++) {
  2362.             /* Compute sc = +/-scale and tc = +/-scale.
  2363.              * Not +/-1 to avoid cube face selection ambiguity near the edges,
  2364.              * though that can still sometimes happen with this scale factor...
  2365.              */
  2366.             const GLfloat scale = 0.9999f;
  2367.             const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
  2368.             const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
  2369.  
  2370.             switch (faceTarget) {
  2371.             case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
  2372.                verts[i].s = 1.0f;
  2373.                verts[i].t = -tc;
  2374.                verts[i].r = -sc;
  2375.                break;
  2376.             case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
  2377.                verts[i].s = -1.0f;
  2378.                verts[i].t = -tc;
  2379.                verts[i].r = sc;
  2380.                break;
  2381.             case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
  2382.                verts[i].s = sc;
  2383.                verts[i].t = 1.0f;
  2384.                verts[i].r = tc;
  2385.                break;
  2386.             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
  2387.                verts[i].s = sc;
  2388.                verts[i].t = -1.0f;
  2389.                verts[i].r = -tc;
  2390.                break;
  2391.             case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
  2392.                verts[i].s = sc;
  2393.                verts[i].t = -tc;
  2394.                verts[i].r = 1.0f;
  2395.                break;
  2396.             case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
  2397.                verts[i].s = -sc;
  2398.                verts[i].t = -tc;
  2399.                verts[i].r = -1.0f;
  2400.                break;
  2401.             default:
  2402.                assert(0);
  2403.             }
  2404.          }
  2405.       }
  2406.    }
  2407.  
  2408.    _mesa_set_enable(ctx, target, GL_TRUE);
  2409.  
  2410.    /* setup vertex positions */
  2411.    {
  2412.       verts[0].x = 0.0F;
  2413.       verts[0].y = 0.0F;
  2414.       verts[1].x = 1.0F;
  2415.       verts[1].y = 0.0F;
  2416.       verts[2].x = 1.0F;
  2417.       verts[2].y = 1.0F;
  2418.       verts[3].x = 0.0F;
  2419.       verts[3].y = 1.0F;
  2420.      
  2421.       /* upload new vertex data */
  2422.       _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
  2423.    }
  2424.  
  2425.    /* setup projection matrix */
  2426.    _mesa_MatrixMode(GL_PROJECTION);
  2427.    _mesa_LoadIdentity();
  2428.    _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
  2429.  
  2430.    /* texture is already locked, unlock now */
  2431.    _mesa_unlock_texture(ctx, texObj);
  2432.  
  2433.    for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
  2434.       const struct gl_texture_image *srcImage;
  2435.       const GLuint srcLevel = dstLevel - 1;
  2436.       GLsizei srcWidth, srcHeight, srcDepth;
  2437.       GLsizei dstWidth, dstHeight, dstDepth;
  2438.       GLenum status;
  2439.  
  2440.       srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
  2441.       assert(srcImage->Border == 0); /* XXX we can fix this */
  2442.  
  2443.       /* src size w/out border */
  2444.       srcWidth = srcImage->Width - 2 * border;
  2445.       srcHeight = srcImage->Height - 2 * border;
  2446.       srcDepth = srcImage->Depth - 2 * border;
  2447.  
  2448.       /* new dst size w/ border */
  2449.       dstWidth = MAX2(1, srcWidth / 2) + 2 * border;
  2450.       dstHeight = MAX2(1, srcHeight / 2) + 2 * border;
  2451.       dstDepth = MAX2(1, srcDepth / 2) + 2 * border;
  2452.  
  2453.       if (dstWidth == srcImage->Width &&
  2454.           dstHeight == srcImage->Height &&
  2455.           dstDepth == srcImage->Depth) {
  2456.          /* all done */
  2457.          break;
  2458.       }
  2459.  
  2460.       /* Set MaxLevel large enough to hold the new level when we allocate it  */
  2461.       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
  2462.  
  2463.       /* Create empty dest image */
  2464.       if (target == GL_TEXTURE_1D) {
  2465.          _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
  2466.                           dstWidth, border,
  2467.                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2468.       }
  2469.       else if (target == GL_TEXTURE_3D) {
  2470.          _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
  2471.                           dstWidth, dstHeight, dstDepth, border,
  2472.                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2473.       }
  2474.       else {
  2475.          /* 2D or cube */
  2476.          _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
  2477.                           dstWidth, dstHeight, border,
  2478.                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2479.  
  2480.          if (target == GL_TEXTURE_CUBE_MAP) {
  2481.             /* If texturing from a cube, we need to make sure all src faces
  2482.              * have been defined (even if we're not sampling from them.)
  2483.              * Otherwise the texture object will be 'incomplete' and
  2484.              * texturing from it will not be allowed.
  2485.              */
  2486.             GLuint face;
  2487.             for (face = 0; face < 6; face++) {
  2488.                if (!texObj->Image[face][srcLevel] ||
  2489.                    texObj->Image[face][srcLevel]->Width != srcWidth) {
  2490.                   _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
  2491.                                    srcLevel, srcImage->InternalFormat,
  2492.                                    srcWidth, srcHeight, border,
  2493.                                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  2494.                }
  2495.             }
  2496.          }
  2497.       }
  2498.  
  2499.       /* limit sampling to src level */
  2500.       _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
  2501.       _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
  2502.  
  2503.       /* Set to draw into the current dstLevel */
  2504.       if (target == GL_TEXTURE_1D) {
  2505.          _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
  2506.                                        GL_COLOR_ATTACHMENT0_EXT,
  2507.                                        target,
  2508.                                        texObj->Name,
  2509.                                        dstLevel);
  2510.       }
  2511.       else if (target == GL_TEXTURE_3D) {
  2512.          GLint zoffset = 0; /* XXX unfinished */
  2513.          _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
  2514.                                        GL_COLOR_ATTACHMENT0_EXT,
  2515.                                        target,
  2516.                                        texObj->Name,
  2517.                                        dstLevel, zoffset);
  2518.       }
  2519.       else {
  2520.          /* 2D / cube */
  2521.          _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
  2522.                                        GL_COLOR_ATTACHMENT0_EXT,
  2523.                                        faceTarget,
  2524.                                        texObj->Name,
  2525.                                        dstLevel);
  2526.       }
  2527.  
  2528.       _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
  2529.  
  2530.       /* sanity check */
  2531.       status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
  2532.       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
  2533.          abort();
  2534.          break;
  2535.       }
  2536.  
  2537.       assert(dstWidth == ctx->DrawBuffer->Width);
  2538.       assert(dstHeight == ctx->DrawBuffer->Height);
  2539.  
  2540.       /* setup viewport */
  2541.       _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
  2542.  
  2543.       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
  2544.    }
  2545.  
  2546.    _mesa_lock_texture(ctx, texObj); /* relock */
  2547.  
  2548.    _mesa_meta_end(ctx);
  2549.  
  2550.    _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
  2551.    _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
  2552.    _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
  2553.    _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
  2554.    _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
  2555.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
  2556.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
  2557.    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave);
  2558.  
  2559.    _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
  2560. }
  2561.  
  2562.  
  2563. /**
  2564.  * Determine the GL data type to use for the temporary image read with
  2565.  * ReadPixels() and passed to Tex[Sub]Image().
  2566.  */
  2567. static GLenum
  2568. get_temp_image_type(struct gl_context *ctx, GLenum baseFormat)
  2569. {
  2570.    switch (baseFormat) {
  2571.    case GL_RGBA:
  2572.    case GL_RGB:
  2573.    case GL_ALPHA:
  2574.    case GL_LUMINANCE:
  2575.    case GL_LUMINANCE_ALPHA:
  2576.    case GL_INTENSITY:
  2577.       if (ctx->DrawBuffer->Visual.redBits <= 8)
  2578.          return GL_UNSIGNED_BYTE;
  2579.       else if (ctx->DrawBuffer->Visual.redBits <= 8)
  2580.          return GL_UNSIGNED_SHORT;
  2581.       else
  2582.          return GL_FLOAT;
  2583.    case GL_DEPTH_COMPONENT:
  2584.       return GL_UNSIGNED_INT;
  2585.    case GL_DEPTH_STENCIL:
  2586.       return GL_UNSIGNED_INT_24_8;
  2587.    default:
  2588.       _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
  2589.       return 0;
  2590.    }
  2591. }
  2592.  
  2593.  
  2594. /**
  2595.  * Helper for _mesa_meta_CopyTexImage1/2D() functions.
  2596.  * Have to be careful with locking and meta state for pixel transfer.
  2597.  */
  2598. static void
  2599. copy_tex_image(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
  2600.                GLenum internalFormat, GLint x, GLint y,
  2601.                GLsizei width, GLsizei height, GLint border)
  2602. {
  2603.    struct gl_texture_object *texObj;
  2604.    struct gl_texture_image *texImage;
  2605.    GLenum format, type;
  2606.    GLint bpp;
  2607.    void *buf;
  2608.  
  2609.    texObj = _mesa_get_current_tex_object(ctx, target);
  2610.    texImage = _mesa_get_tex_image(ctx, texObj, target, level);
  2611.  
  2612.    /* Choose format/type for temporary image buffer */
  2613.    format = _mesa_base_tex_format(ctx, internalFormat);
  2614.    type = get_temp_image_type(ctx, format);
  2615.    bpp = _mesa_bytes_per_pixel(format, type);
  2616.    if (bpp <= 0) {
  2617.       _mesa_problem(ctx, "Bad bpp in meta copy_tex_image()");
  2618.       return;
  2619.    }
  2620.  
  2621.    /*
  2622.     * Alloc image buffer (XXX could use a PBO)
  2623.     */
  2624.    buf = malloc(width * height * bpp);
  2625.    if (!buf) {
  2626.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
  2627.       return;
  2628.    }
  2629.  
  2630.    _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
  2631.  
  2632.    /*
  2633.     * Read image from framebuffer (disable pixel transfer ops)
  2634.     */
  2635.    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
  2636.    ctx->Driver.ReadPixels(ctx, x, y, width, height,
  2637.                           format, type, &ctx->Pack, buf);
  2638.    _mesa_meta_end(ctx);
  2639.  
  2640.    if (texImage->Data) {
  2641.       ctx->Driver.FreeTexImageData(ctx, texImage);
  2642.    }
  2643.  
  2644.    /* The texture's format was already chosen in _mesa_CopyTexImage() */
  2645.    ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
  2646.  
  2647.    /*
  2648.     * Store texture data (with pixel transfer ops)
  2649.     */
  2650.    _mesa_meta_begin(ctx, META_PIXEL_STORE);
  2651.  
  2652.    _mesa_update_state(ctx); /* to update pixel transfer state */
  2653.  
  2654.    if (target == GL_TEXTURE_1D) {
  2655.       ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
  2656.                              width, border, format, type,
  2657.                              buf, &ctx->Unpack, texObj, texImage);
  2658.    }
  2659.    else {
  2660.       ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
  2661.                              width, height, border, format, type,
  2662.                              buf, &ctx->Unpack, texObj, texImage);
  2663.    }
  2664.    _mesa_meta_end(ctx);
  2665.  
  2666.    _mesa_lock_texture(ctx, texObj); /* re-lock */
  2667.  
  2668.    free(buf);
  2669. }
  2670.  
  2671.  
  2672. void
  2673. _mesa_meta_CopyTexImage1D(struct gl_context *ctx, GLenum target, GLint level,
  2674.                           GLenum internalFormat, GLint x, GLint y,
  2675.                           GLsizei width, GLint border)
  2676. {
  2677.    copy_tex_image(ctx, 1, target, level, internalFormat, x, y,
  2678.                   width, 1, border);
  2679. }
  2680.  
  2681.  
  2682. void
  2683. _mesa_meta_CopyTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
  2684.                           GLenum internalFormat, GLint x, GLint y,
  2685.                           GLsizei width, GLsizei height, GLint border)
  2686. {
  2687.    copy_tex_image(ctx, 2, target, level, internalFormat, x, y,
  2688.                   width, height, border);
  2689. }
  2690.  
  2691.  
  2692.  
  2693. /**
  2694.  * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
  2695.  * Have to be careful with locking and meta state for pixel transfer.
  2696.  */
  2697. static void
  2698. copy_tex_sub_image(struct gl_context *ctx,
  2699.                    GLuint dims, GLenum target, GLint level,
  2700.                    GLint xoffset, GLint yoffset, GLint zoffset,
  2701.                    GLint x, GLint y,
  2702.                    GLsizei width, GLsizei height)
  2703. {
  2704.    struct gl_texture_object *texObj;
  2705.    struct gl_texture_image *texImage;
  2706.    GLenum format, type;
  2707.    GLint bpp;
  2708.    void *buf;
  2709.  
  2710.    texObj = _mesa_get_current_tex_object(ctx, target);
  2711.    texImage = _mesa_select_tex_image(ctx, texObj, target, level);
  2712.  
  2713.    /* Choose format/type for temporary image buffer */
  2714.    format = _mesa_get_format_base_format(texImage->TexFormat);
  2715.    type = get_temp_image_type(ctx, format);
  2716.    bpp = _mesa_bytes_per_pixel(format, type);
  2717.    if (bpp <= 0) {
  2718.       _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()");
  2719.       return;
  2720.    }
  2721.  
  2722.    /*
  2723.     * Alloc image buffer (XXX could use a PBO)
  2724.     */
  2725.    buf = malloc(width * height * bpp);
  2726.    if (!buf) {
  2727.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
  2728.       return;
  2729.    }
  2730.  
  2731.    _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
  2732.  
  2733.    /*
  2734.     * Read image from framebuffer (disable pixel transfer ops)
  2735.     */
  2736.    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
  2737.    ctx->Driver.ReadPixels(ctx, x, y, width, height,
  2738.                           format, type, &ctx->Pack, buf);
  2739.    _mesa_meta_end(ctx);
  2740.  
  2741.    _mesa_update_state(ctx); /* to update pixel transfer state */
  2742.  
  2743.    /*
  2744.     * Store texture data (with pixel transfer ops)
  2745.     */
  2746.    _mesa_meta_begin(ctx, META_PIXEL_STORE);
  2747.    if (target == GL_TEXTURE_1D) {
  2748.       ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
  2749.                                 width, format, type, buf,
  2750.                                 &ctx->Unpack, texObj, texImage);
  2751.    }
  2752.    else if (target == GL_TEXTURE_3D) {
  2753.       ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
  2754.                                 width, height, 1, format, type, buf,
  2755.                                 &ctx->Unpack, texObj, texImage);
  2756.    }
  2757.    else {
  2758.       ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
  2759.                                 width, height, format, type, buf,
  2760.                                 &ctx->Unpack, texObj, texImage);
  2761.    }
  2762.    _mesa_meta_end(ctx);
  2763.  
  2764.    _mesa_lock_texture(ctx, texObj); /* re-lock */
  2765.  
  2766.    free(buf);
  2767. }
  2768.  
  2769.  
  2770. void
  2771. _mesa_meta_CopyTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
  2772.                              GLint xoffset,
  2773.                              GLint x, GLint y, GLsizei width)
  2774. {
  2775.    copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
  2776.                       x, y, width, 1);
  2777. }
  2778.  
  2779.  
  2780. void
  2781. _mesa_meta_CopyTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
  2782.                              GLint xoffset, GLint yoffset,
  2783.                              GLint x, GLint y,
  2784.                              GLsizei width, GLsizei height)
  2785. {
  2786.    copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
  2787.                       x, y, width, height);
  2788. }
  2789.  
  2790.  
  2791. void
  2792. _mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
  2793.                              GLint xoffset, GLint yoffset, GLint zoffset,
  2794.                              GLint x, GLint y,
  2795.                              GLsizei width, GLsizei height)
  2796. {
  2797.    copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
  2798.                       x, y, width, height);
  2799. }
  2800.  
  2801.  
  2802. void
  2803. _mesa_meta_CopyColorTable(struct gl_context *ctx,
  2804.                           GLenum target, GLenum internalformat,
  2805.                           GLint x, GLint y, GLsizei width)
  2806. {
  2807.    GLfloat *buf;
  2808.  
  2809.    buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
  2810.    if (!buf) {
  2811.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
  2812.       return;
  2813.    }
  2814.  
  2815.    /*
  2816.     * Read image from framebuffer (disable pixel transfer ops)
  2817.     */
  2818.    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
  2819.    ctx->Driver.ReadPixels(ctx, x, y, width, 1,
  2820.                           GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
  2821.  
  2822.    _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
  2823.  
  2824.    _mesa_meta_end(ctx);
  2825.  
  2826.    free(buf);
  2827. }
  2828.  
  2829.  
  2830. void
  2831. _mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start,
  2832.                              GLint x, GLint y, GLsizei width)
  2833. {
  2834.    GLfloat *buf;
  2835.  
  2836.    buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
  2837.    if (!buf) {
  2838.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
  2839.       return;
  2840.    }
  2841.  
  2842.    /*
  2843.     * Read image from framebuffer (disable pixel transfer ops)
  2844.     */
  2845.    _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
  2846.    ctx->Driver.ReadPixels(ctx, x, y, width, 1,
  2847.                           GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
  2848.  
  2849.    _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
  2850.  
  2851.    _mesa_meta_end(ctx);
  2852.  
  2853.    free(buf);
  2854. }
  2855.