Subversion Repositories Kolibri OS

Rev

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

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