Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  * Copyright 2009 VMware, Inc.  All Rights Reserved.
  6.  * Copyright © 2010-2011 Intel Corporation
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the
  10.  * "Software"), to deal in the Software without restriction, including
  11.  * without limitation the rights to use, copy, modify, merge, publish,
  12.  * distribute, sub license, and/or sell copies of the Software, and to
  13.  * permit persons to whom the Software is furnished to do so, subject to
  14.  * the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice (including the
  17.  * next paragraph) shall be included in all copies or substantial portions
  18.  * of the Software.
  19.  *
  20.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  23.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  24.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  25.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  26.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27.  *
  28.  **************************************************************************/
  29.  
  30. extern "C" {
  31. #include "glheader.h"
  32. #include "imports.h"
  33. #include "mtypes.h"
  34. #include "main/context.h"
  35. #include "main/uniforms.h"
  36. #include "main/macros.h"
  37. #include "main/samplerobj.h"
  38. #include "program/program.h"
  39. #include "program/prog_parameter.h"
  40. #include "program/prog_cache.h"
  41. #include "program/prog_instruction.h"
  42. #include "program/prog_print.h"
  43. #include "program/prog_statevars.h"
  44. #include "program/programopt.h"
  45. #include "texenvprogram.h"
  46. }
  47. #include "main/uniforms.h"
  48. #include "../glsl/glsl_types.h"
  49. #include "../glsl/ir.h"
  50. #include "../glsl/ir_builder.h"
  51. #include "../glsl/glsl_symbol_table.h"
  52. #include "../glsl/glsl_parser_extras.h"
  53. #include "../glsl/ir_optimization.h"
  54. #include "../program/ir_to_mesa.h"
  55.  
  56. using namespace ir_builder;
  57.  
  58. /*
  59.  * Note on texture units:
  60.  *
  61.  * The number of texture units supported by fixed-function fragment
  62.  * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS.
  63.  * That's because there's a one-to-one correspondence between texture
  64.  * coordinates and samplers in fixed-function processing.
  65.  *
  66.  * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS
  67.  * sets of texcoords, so is fixed-function fragment processing.
  68.  *
  69.  * We can safely use ctx->Const.MaxTextureUnits for loop bounds.
  70.  */
  71.  
  72.  
  73. struct texenvprog_cache_item
  74. {
  75.    GLuint hash;
  76.    void *key;
  77.    struct gl_shader_program *data;
  78.    struct texenvprog_cache_item *next;
  79. };
  80.  
  81. static GLboolean
  82. texenv_doing_secondary_color(struct gl_context *ctx)
  83. {
  84.    if (ctx->Light.Enabled &&
  85.        (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))
  86.       return GL_TRUE;
  87.  
  88.    if (ctx->Fog.ColorSumEnabled)
  89.       return GL_TRUE;
  90.  
  91.    return GL_FALSE;
  92. }
  93.  
  94. struct mode_opt {
  95. #ifdef __GNUC__
  96.    __extension__ GLubyte Source:4;  /**< SRC_x */
  97.    __extension__ GLubyte Operand:3; /**< OPR_x */
  98. #else
  99.    GLubyte Source;  /**< SRC_x */
  100.    GLubyte Operand; /**< OPR_x */
  101. #endif
  102. };
  103.  
  104. struct state_key {
  105.    GLuint nr_enabled_units:8;
  106.    GLuint enabled_units:8;
  107.    GLuint separate_specular:1;
  108.    GLuint fog_enabled:1;
  109.    GLuint fog_mode:2;          /**< FOG_x */
  110.    GLuint inputs_available:12;
  111.    GLuint num_draw_buffers:4;
  112.  
  113.    /* NOTE: This array of structs must be last! (see "keySize" below) */
  114.    struct {
  115.       GLuint enabled:1;
  116.       GLuint source_index:4;   /**< TEXTURE_x_INDEX */
  117.       GLuint shadow:1;
  118.       GLuint ScaleShiftRGB:2;
  119.       GLuint ScaleShiftA:2;
  120.  
  121.       GLuint NumArgsRGB:3;  /**< up to MAX_COMBINER_TERMS */
  122.       GLuint ModeRGB:5;     /**< MODE_x */
  123.  
  124.       GLuint NumArgsA:3;  /**< up to MAX_COMBINER_TERMS */
  125.       GLuint ModeA:5;     /**< MODE_x */
  126.  
  127.       struct mode_opt OptRGB[MAX_COMBINER_TERMS];
  128.       struct mode_opt OptA[MAX_COMBINER_TERMS];
  129.    } unit[MAX_TEXTURE_UNITS];
  130. };
  131.  
  132. #define FOG_LINEAR  0
  133. #define FOG_EXP     1
  134. #define FOG_EXP2    2
  135. #define FOG_UNKNOWN 3
  136.  
  137. static GLuint translate_fog_mode( GLenum mode )
  138. {
  139.    switch (mode) {
  140.    case GL_LINEAR: return FOG_LINEAR;
  141.    case GL_EXP: return FOG_EXP;
  142.    case GL_EXP2: return FOG_EXP2;
  143.    default: return FOG_UNKNOWN;
  144.    }
  145. }
  146.  
  147. #define OPR_SRC_COLOR           0
  148. #define OPR_ONE_MINUS_SRC_COLOR 1
  149. #define OPR_SRC_ALPHA           2
  150. #define OPR_ONE_MINUS_SRC_ALPHA 3
  151. #define OPR_ZERO                4
  152. #define OPR_ONE                 5
  153. #define OPR_UNKNOWN             7
  154.  
  155. static GLuint translate_operand( GLenum operand )
  156. {
  157.    switch (operand) {
  158.    case GL_SRC_COLOR: return OPR_SRC_COLOR;
  159.    case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR;
  160.    case GL_SRC_ALPHA: return OPR_SRC_ALPHA;
  161.    case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA;
  162.    case GL_ZERO: return OPR_ZERO;
  163.    case GL_ONE: return OPR_ONE;
  164.    default:
  165.       assert(0);
  166.       return OPR_UNKNOWN;
  167.    }
  168. }
  169.  
  170. #define SRC_TEXTURE  0
  171. #define SRC_TEXTURE0 1
  172. #define SRC_TEXTURE1 2
  173. #define SRC_TEXTURE2 3
  174. #define SRC_TEXTURE3 4
  175. #define SRC_TEXTURE4 5
  176. #define SRC_TEXTURE5 6
  177. #define SRC_TEXTURE6 7
  178. #define SRC_TEXTURE7 8
  179. #define SRC_CONSTANT 9
  180. #define SRC_PRIMARY_COLOR 10
  181. #define SRC_PREVIOUS 11
  182. #define SRC_ZERO     12
  183. #define SRC_UNKNOWN  15
  184.  
  185. static GLuint translate_source( GLenum src )
  186. {
  187.    switch (src) {
  188.    case GL_TEXTURE: return SRC_TEXTURE;
  189.    case GL_TEXTURE0:
  190.    case GL_TEXTURE1:
  191.    case GL_TEXTURE2:
  192.    case GL_TEXTURE3:
  193.    case GL_TEXTURE4:
  194.    case GL_TEXTURE5:
  195.    case GL_TEXTURE6:
  196.    case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0);
  197.    case GL_CONSTANT: return SRC_CONSTANT;
  198.    case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR;
  199.    case GL_PREVIOUS: return SRC_PREVIOUS;
  200.    case GL_ZERO:
  201.       return SRC_ZERO;
  202.    default:
  203.       assert(0);
  204.       return SRC_UNKNOWN;
  205.    }
  206. }
  207.  
  208. #define MODE_REPLACE                     0  /* r = a0 */
  209. #define MODE_MODULATE                    1  /* r = a0 * a1 */
  210. #define MODE_ADD                         2  /* r = a0 + a1 */
  211. #define MODE_ADD_SIGNED                  3  /* r = a0 + a1 - 0.5 */
  212. #define MODE_INTERPOLATE                 4  /* r = a0 * a2 + a1 * (1 - a2) */
  213. #define MODE_SUBTRACT                    5  /* r = a0 - a1 */
  214. #define MODE_DOT3_RGB                    6  /* r = a0 . a1 */
  215. #define MODE_DOT3_RGB_EXT                7  /* r = a0 . a1 */
  216. #define MODE_DOT3_RGBA                   8  /* r = a0 . a1 */
  217. #define MODE_DOT3_RGBA_EXT               9  /* r = a0 . a1 */
  218. #define MODE_MODULATE_ADD_ATI           10  /* r = a0 * a2 + a1 */
  219. #define MODE_MODULATE_SIGNED_ADD_ATI    11  /* r = a0 * a2 + a1 - 0.5 */
  220. #define MODE_MODULATE_SUBTRACT_ATI      12  /* r = a0 * a2 - a1 */
  221. #define MODE_ADD_PRODUCTS               13  /* r = a0 * a1 + a2 * a3 */
  222. #define MODE_ADD_PRODUCTS_SIGNED        14  /* r = a0 * a1 + a2 * a3 - 0.5 */
  223. #define MODE_BUMP_ENVMAP_ATI            15  /* special */
  224. #define MODE_UNKNOWN                    16
  225.  
  226. /**
  227.  * Translate GL combiner state into a MODE_x value
  228.  */
  229. static GLuint translate_mode( GLenum envMode, GLenum mode )
  230. {
  231.    switch (mode) {
  232.    case GL_REPLACE: return MODE_REPLACE;
  233.    case GL_MODULATE: return MODE_MODULATE;
  234.    case GL_ADD:
  235.       if (envMode == GL_COMBINE4_NV)
  236.          return MODE_ADD_PRODUCTS;
  237.       else
  238.          return MODE_ADD;
  239.    case GL_ADD_SIGNED:
  240.       if (envMode == GL_COMBINE4_NV)
  241.          return MODE_ADD_PRODUCTS_SIGNED;
  242.       else
  243.          return MODE_ADD_SIGNED;
  244.    case GL_INTERPOLATE: return MODE_INTERPOLATE;
  245.    case GL_SUBTRACT: return MODE_SUBTRACT;
  246.    case GL_DOT3_RGB: return MODE_DOT3_RGB;
  247.    case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT;
  248.    case GL_DOT3_RGBA: return MODE_DOT3_RGBA;
  249.    case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT;
  250.    case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI;
  251.    case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI;
  252.    case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI;
  253.    case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI;
  254.    default:
  255.       assert(0);
  256.       return MODE_UNKNOWN;
  257.    }
  258. }
  259.  
  260.  
  261. /**
  262.  * Do we need to clamp the results of the given texture env/combine mode?
  263.  * If the inputs to the mode are in [0,1] we don't always have to clamp
  264.  * the results.
  265.  */
  266. static GLboolean
  267. need_saturate( GLuint mode )
  268. {
  269.    switch (mode) {
  270.    case MODE_REPLACE:
  271.    case MODE_MODULATE:
  272.    case MODE_INTERPOLATE:
  273.       return GL_FALSE;
  274.    case MODE_ADD:
  275.    case MODE_ADD_SIGNED:
  276.    case MODE_SUBTRACT:
  277.    case MODE_DOT3_RGB:
  278.    case MODE_DOT3_RGB_EXT:
  279.    case MODE_DOT3_RGBA:
  280.    case MODE_DOT3_RGBA_EXT:
  281.    case MODE_MODULATE_ADD_ATI:
  282.    case MODE_MODULATE_SIGNED_ADD_ATI:
  283.    case MODE_MODULATE_SUBTRACT_ATI:
  284.    case MODE_ADD_PRODUCTS:
  285.    case MODE_ADD_PRODUCTS_SIGNED:
  286.    case MODE_BUMP_ENVMAP_ATI:
  287.       return GL_TRUE;
  288.    default:
  289.       assert(0);
  290.       return GL_FALSE;
  291.    }
  292. }
  293.  
  294.  
  295.  
  296. /**
  297.  * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX.
  298.  */
  299. static GLuint translate_tex_src_bit( GLbitfield bit )
  300. {
  301.    ASSERT(bit);
  302.    return ffs(bit) - 1;
  303. }
  304.  
  305.  
  306. #define VERT_BIT_TEX_ANY    (0xff << VERT_ATTRIB_TEX0)
  307.  
  308. /**
  309.  * Identify all possible varying inputs.  The fragment program will
  310.  * never reference non-varying inputs, but will track them via state
  311.  * constants instead.
  312.  *
  313.  * This function figures out all the inputs that the fragment program
  314.  * has access to.  The bitmask is later reduced to just those which
  315.  * are actually referenced.
  316.  */
  317. static GLbitfield get_fp_input_mask( struct gl_context *ctx )
  318. {
  319.    /* _NEW_PROGRAM */
  320.    const GLboolean vertexShader =
  321.       (ctx->Shader.CurrentVertexProgram &&
  322.        ctx->Shader.CurrentVertexProgram->LinkStatus &&
  323.        ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]);
  324.    const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
  325.    GLbitfield fp_inputs = 0x0;
  326.  
  327.    if (ctx->VertexProgram._Overriden) {
  328.       /* Somebody's messing with the vertex program and we don't have
  329.        * a clue what's happening.  Assume that it could be producing
  330.        * all possible outputs.
  331.        */
  332.       fp_inputs = ~0;
  333.    }
  334.    else if (ctx->RenderMode == GL_FEEDBACK) {
  335.       /* _NEW_RENDERMODE */
  336.       fp_inputs = (VARYING_BIT_COL0 | VARYING_BIT_TEX0);
  337.    }
  338.    else if (!(vertexProgram || vertexShader)) {
  339.       /* Fixed function vertex logic */
  340.       /* _NEW_VARYING_VP_INPUTS */
  341.       GLbitfield64 varying_inputs = ctx->varying_vp_inputs;
  342.  
  343.       /* These get generated in the setup routine regardless of the
  344.        * vertex program:
  345.        */
  346.       /* _NEW_POINT */
  347.       if (ctx->Point.PointSprite)
  348.          varying_inputs |= VARYING_BITS_TEX_ANY;
  349.  
  350.       /* First look at what values may be computed by the generated
  351.        * vertex program:
  352.        */
  353.       /* _NEW_LIGHT */
  354.       if (ctx->Light.Enabled) {
  355.          fp_inputs |= VARYING_BIT_COL0;
  356.  
  357.          if (texenv_doing_secondary_color(ctx))
  358.             fp_inputs |= VARYING_BIT_COL1;
  359.       }
  360.  
  361.       /* _NEW_TEXTURE */
  362.       fp_inputs |= (ctx->Texture._TexGenEnabled |
  363.                     ctx->Texture._TexMatEnabled) << VARYING_SLOT_TEX0;
  364.  
  365.       /* Then look at what might be varying as a result of enabled
  366.        * arrays, etc:
  367.        */
  368.       if (varying_inputs & VERT_BIT_COLOR0)
  369.          fp_inputs |= VARYING_BIT_COL0;
  370.       if (varying_inputs & VERT_BIT_COLOR1)
  371.          fp_inputs |= VARYING_BIT_COL1;
  372.  
  373.       fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0)
  374.                     << VARYING_SLOT_TEX0);
  375.  
  376.    }
  377.    else {
  378.       /* calculate from vp->outputs */
  379.       struct gl_program *vprog;
  380.       GLbitfield64 vp_outputs;
  381.  
  382.       /* Choose GLSL vertex shader over ARB vertex program.  Need this
  383.        * since vertex shader state validation comes after fragment state
  384.        * validation (see additional comments in state.c).
  385.        */
  386.       if (vertexShader)
  387.          vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
  388.       else
  389.          vprog = &ctx->VertexProgram.Current->Base;
  390.  
  391.       vp_outputs = vprog->OutputsWritten;
  392.  
  393.       /* These get generated in the setup routine regardless of the
  394.        * vertex program:
  395.        */
  396.       /* _NEW_POINT */
  397.       if (ctx->Point.PointSprite)
  398.          vp_outputs |= VARYING_BITS_TEX_ANY;
  399.  
  400.       if (vp_outputs & (1 << VARYING_SLOT_COL0))
  401.          fp_inputs |= VARYING_BIT_COL0;
  402.       if (vp_outputs & (1 << VARYING_SLOT_COL1))
  403.          fp_inputs |= VARYING_BIT_COL1;
  404.  
  405.       fp_inputs |= (((vp_outputs & VARYING_BITS_TEX_ANY) >> VARYING_SLOT_TEX0)
  406.                     << VARYING_SLOT_TEX0);
  407.    }
  408.    
  409.    return fp_inputs;
  410. }
  411.  
  412.  
  413. /**
  414.  * Examine current texture environment state and generate a unique
  415.  * key to identify it.
  416.  */
  417. static GLuint make_state_key( struct gl_context *ctx,  struct state_key *key )
  418. {
  419.    GLuint i, j;
  420.    GLbitfield inputs_referenced = VARYING_BIT_COL0;
  421.    const GLbitfield inputs_available = get_fp_input_mask( ctx );
  422.    GLuint keySize;
  423.  
  424.    memset(key, 0, sizeof(*key));
  425.  
  426.    /* _NEW_TEXTURE */
  427.    for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
  428.       const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
  429.       const struct gl_texture_object *texObj = texUnit->_Current;
  430.       const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine;
  431.       const struct gl_sampler_object *samp;
  432.       GLenum format;
  433.  
  434.       if (!texUnit->_ReallyEnabled || !texUnit->Enabled)
  435.          continue;
  436.  
  437.       samp = _mesa_get_samplerobj(ctx, i);
  438.       format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
  439.  
  440.       key->unit[i].enabled = 1;
  441.       key->enabled_units |= (1<<i);
  442.       key->nr_enabled_units = i + 1;
  443.       inputs_referenced |= VARYING_BIT_TEX(i);
  444.  
  445.       key->unit[i].source_index =
  446.          translate_tex_src_bit(texUnit->_ReallyEnabled);
  447.  
  448.       key->unit[i].shadow =
  449.          ((samp->CompareMode == GL_COMPARE_R_TO_TEXTURE) &&
  450.           ((format == GL_DEPTH_COMPONENT) ||
  451.            (format == GL_DEPTH_STENCIL_EXT)));
  452.  
  453.       key->unit[i].NumArgsRGB = comb->_NumArgsRGB;
  454.       key->unit[i].NumArgsA = comb->_NumArgsA;
  455.  
  456.       key->unit[i].ModeRGB =
  457.          translate_mode(texUnit->EnvMode, comb->ModeRGB);
  458.       key->unit[i].ModeA =
  459.          translate_mode(texUnit->EnvMode, comb->ModeA);
  460.  
  461.       key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB;
  462.       key->unit[i].ScaleShiftA = comb->ScaleShiftA;
  463.  
  464.       for (j = 0; j < MAX_COMBINER_TERMS; j++) {
  465.          key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]);
  466.          key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]);
  467.          key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]);
  468.          key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]);
  469.       }
  470.  
  471.       if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
  472.          /* requires some special translation */
  473.          key->unit[i].NumArgsRGB = 2;
  474.          key->unit[i].ScaleShiftRGB = 0;
  475.          key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR;
  476.          key->unit[i].OptRGB[0].Source = SRC_TEXTURE;
  477.          key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR;
  478.          key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0;
  479.        }
  480.    }
  481.  
  482.    /* _NEW_LIGHT | _NEW_FOG */
  483.    if (texenv_doing_secondary_color(ctx)) {
  484.       key->separate_specular = 1;
  485.       inputs_referenced |= VARYING_BIT_COL1;
  486.    }
  487.  
  488.    /* _NEW_FOG */
  489.    if (ctx->Fog.Enabled) {
  490.       key->fog_enabled = 1;
  491.       key->fog_mode = translate_fog_mode(ctx->Fog.Mode);
  492.       inputs_referenced |= VARYING_BIT_FOGC; /* maybe */
  493.    }
  494.  
  495.    /* _NEW_BUFFERS */
  496.    key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
  497.  
  498.    /* _NEW_COLOR */
  499.    if (ctx->Color.AlphaEnabled && key->num_draw_buffers == 0) {
  500.       /* if alpha test is enabled we need to emit at least one color */
  501.       key->num_draw_buffers = 1;
  502.    }
  503.  
  504.    key->inputs_available = (inputs_available & inputs_referenced);
  505.  
  506.    /* compute size of state key, ignoring unused texture units */
  507.    keySize = sizeof(*key) - sizeof(key->unit)
  508.       + key->nr_enabled_units * sizeof(key->unit[0]);
  509.  
  510.    return keySize;
  511. }
  512.  
  513.  
  514. /** State used to build the fragment program:
  515.  */
  516. class texenv_fragment_program : public ir_factory {
  517. public:
  518.    struct gl_shader_program *shader_program;
  519.    struct gl_shader *shader;
  520.    exec_list *top_instructions;
  521.    struct state_key *state;
  522.  
  523.    ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS];
  524.    /* Reg containing each texture unit's sampled texture color,
  525.     * else undef.
  526.     */
  527.  
  528.    /* Texcoord override from bumpmapping. */
  529.    ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS];
  530.  
  531.    /* Reg containing texcoord for a texture unit,
  532.     * needed for bump mapping, else undef.
  533.     */
  534.  
  535.    ir_rvalue *src_previous;     /**< Reg containing color from previous
  536.                                  * stage.  May need to be decl'd.
  537.                                  */
  538. };
  539.  
  540. static ir_rvalue *
  541. get_current_attrib(texenv_fragment_program *p, GLuint attrib)
  542. {
  543.    ir_variable *current;
  544.    ir_rvalue *val;
  545.  
  546.    current = p->shader->symbols->get_variable("gl_CurrentAttribFragMESA");
  547.    current->max_array_access = MAX2(current->max_array_access, attrib);
  548.    val = new(p->mem_ctx) ir_dereference_variable(current);
  549.    ir_rvalue *index = new(p->mem_ctx) ir_constant(attrib);
  550.    return new(p->mem_ctx) ir_dereference_array(val, index);
  551. }
  552.  
  553. static ir_rvalue *
  554. get_gl_Color(texenv_fragment_program *p)
  555. {
  556.    if (p->state->inputs_available & VARYING_BIT_COL0) {
  557.       ir_variable *var = p->shader->symbols->get_variable("gl_Color");
  558.       assert(var);
  559.       return new(p->mem_ctx) ir_dereference_variable(var);
  560.    } else {
  561.       return get_current_attrib(p, VERT_ATTRIB_COLOR0);
  562.    }
  563. }
  564.  
  565. static ir_rvalue *
  566. get_source(texenv_fragment_program *p,
  567.            GLuint src, GLuint unit)
  568. {
  569.    ir_variable *var;
  570.    ir_dereference *deref;
  571.  
  572.    switch (src) {
  573.    case SRC_TEXTURE:
  574.       return new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]);
  575.  
  576.    case SRC_TEXTURE0:
  577.    case SRC_TEXTURE1:
  578.    case SRC_TEXTURE2:
  579.    case SRC_TEXTURE3:
  580.    case SRC_TEXTURE4:
  581.    case SRC_TEXTURE5:
  582.    case SRC_TEXTURE6:
  583.    case SRC_TEXTURE7:
  584.       return new(p->mem_ctx)
  585.          ir_dereference_variable(p->src_texture[src - SRC_TEXTURE0]);
  586.  
  587.    case SRC_CONSTANT:
  588.       var = p->shader->symbols->get_variable("gl_TextureEnvColor");
  589.       assert(var);
  590.       deref = new(p->mem_ctx) ir_dereference_variable(var);
  591.       var->max_array_access = MAX2(var->max_array_access, unit);
  592.       return new(p->mem_ctx) ir_dereference_array(deref,
  593.                                                   new(p->mem_ctx) ir_constant(unit));
  594.  
  595.    case SRC_PRIMARY_COLOR:
  596.       var = p->shader->symbols->get_variable("gl_Color");
  597.       assert(var);
  598.       return new(p->mem_ctx) ir_dereference_variable(var);
  599.  
  600.    case SRC_ZERO:
  601.       return new(p->mem_ctx) ir_constant(0.0f);
  602.  
  603.    case SRC_PREVIOUS:
  604.       if (!p->src_previous) {
  605.          return get_gl_Color(p);
  606.       } else {
  607.          return p->src_previous->clone(p->mem_ctx, NULL);
  608.       }
  609.  
  610.    default:
  611.       assert(0);
  612.       return NULL;
  613.    }
  614. }
  615.  
  616. static ir_rvalue *
  617. emit_combine_source(texenv_fragment_program *p,
  618.                     GLuint unit,
  619.                     GLuint source,
  620.                     GLuint operand)
  621. {
  622.    ir_rvalue *src;
  623.  
  624.    src = get_source(p, source, unit);
  625.  
  626.    switch (operand) {
  627.    case OPR_ONE_MINUS_SRC_COLOR:
  628.       return sub(new(p->mem_ctx) ir_constant(1.0f), src);
  629.  
  630.    case OPR_SRC_ALPHA:
  631.       return src->type->is_scalar() ? src : swizzle_w(src);
  632.  
  633.    case OPR_ONE_MINUS_SRC_ALPHA: {
  634.       ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src);
  635.  
  636.       return sub(new(p->mem_ctx) ir_constant(1.0f), scalar);
  637.    }
  638.  
  639.    case OPR_ZERO:
  640.       return new(p->mem_ctx) ir_constant(0.0f);
  641.    case OPR_ONE:
  642.       return new(p->mem_ctx) ir_constant(1.0f);
  643.    case OPR_SRC_COLOR:
  644.       return src;
  645.    default:
  646.       assert(0);
  647.       return src;
  648.    }
  649. }
  650.  
  651. /**
  652.  * Check if the RGB and Alpha sources and operands match for the given
  653.  * texture unit's combinder state.  When the RGB and A sources and
  654.  * operands match, we can emit fewer instructions.
  655.  */
  656. static GLboolean args_match( const struct state_key *key, GLuint unit )
  657. {
  658.    GLuint i, numArgs = key->unit[unit].NumArgsRGB;
  659.  
  660.    for (i = 0; i < numArgs; i++) {
  661.       if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source)
  662.          return GL_FALSE;
  663.  
  664.       switch (key->unit[unit].OptA[i].Operand) {
  665.       case OPR_SRC_ALPHA:
  666.          switch (key->unit[unit].OptRGB[i].Operand) {
  667.          case OPR_SRC_COLOR:
  668.          case OPR_SRC_ALPHA:
  669.             break;
  670.          default:
  671.             return GL_FALSE;
  672.          }
  673.          break;
  674.       case OPR_ONE_MINUS_SRC_ALPHA:
  675.          switch (key->unit[unit].OptRGB[i].Operand) {
  676.          case OPR_ONE_MINUS_SRC_COLOR:
  677.          case OPR_ONE_MINUS_SRC_ALPHA:
  678.             break;
  679.          default:
  680.             return GL_FALSE;
  681.          }
  682.          break;
  683.       default:
  684.          return GL_FALSE;       /* impossible */
  685.       }
  686.    }
  687.  
  688.    return GL_TRUE;
  689. }
  690.  
  691. static ir_rvalue *
  692. smear(texenv_fragment_program *p, ir_rvalue *val)
  693. {
  694.    if (!val->type->is_scalar())
  695.       return val;
  696.  
  697.    return swizzle_xxxx(val);
  698. }
  699.  
  700. static ir_rvalue *
  701. emit_combine(texenv_fragment_program *p,
  702.              GLuint unit,
  703.              GLuint nr,
  704.              GLuint mode,
  705.              const struct mode_opt *opt)
  706. {
  707.    ir_rvalue *src[MAX_COMBINER_TERMS];
  708.    ir_rvalue *tmp0, *tmp1;
  709.    GLuint i;
  710.  
  711.    assert(nr <= MAX_COMBINER_TERMS);
  712.  
  713.    for (i = 0; i < nr; i++)
  714.       src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand );
  715.  
  716.    switch (mode) {
  717.    case MODE_REPLACE:
  718.       return src[0];
  719.  
  720.    case MODE_MODULATE:
  721.       return mul(src[0], src[1]);
  722.  
  723.    case MODE_ADD:
  724.       return add(src[0], src[1]);
  725.  
  726.    case MODE_ADD_SIGNED:
  727.       return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f));
  728.  
  729.    case MODE_INTERPOLATE:
  730.       /* Arg0 * (Arg2) + Arg1 * (1-Arg2) */
  731.       tmp0 = mul(src[0], src[2]);
  732.       tmp1 = mul(src[1], sub(new(p->mem_ctx) ir_constant(1.0f),
  733.                              src[2]->clone(p->mem_ctx, NULL)));
  734.       return add(tmp0, tmp1);
  735.  
  736.    case MODE_SUBTRACT:
  737.       return sub(src[0], src[1]);
  738.  
  739.    case MODE_DOT3_RGBA:
  740.    case MODE_DOT3_RGBA_EXT:
  741.    case MODE_DOT3_RGB_EXT:
  742.    case MODE_DOT3_RGB: {
  743.       tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f));
  744.       tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f));
  745.  
  746.       tmp1 = mul(src[1], new(p->mem_ctx) ir_constant(2.0f));
  747.       tmp1 = add(tmp1, new(p->mem_ctx) ir_constant(-1.0f));
  748.  
  749.       return dot(swizzle_xyz(smear(p, tmp0)), swizzle_xyz(smear(p, tmp1)));
  750.    }
  751.    case MODE_MODULATE_ADD_ATI:
  752.       return add(mul(src[0], src[2]), src[1]);
  753.  
  754.    case MODE_MODULATE_SIGNED_ADD_ATI:
  755.       return add(add(mul(src[0], src[2]), src[1]),
  756.                  new(p->mem_ctx) ir_constant(-0.5f));
  757.  
  758.    case MODE_MODULATE_SUBTRACT_ATI:
  759.       return sub(mul(src[0], src[2]), src[1]);
  760.  
  761.    case MODE_ADD_PRODUCTS:
  762.       return add(mul(src[0], src[1]), mul(src[2], src[3]));
  763.  
  764.    case MODE_ADD_PRODUCTS_SIGNED:
  765.       return add(add(mul(src[0], src[1]), mul(src[2], src[3])),
  766.                  new(p->mem_ctx) ir_constant(-0.5f));
  767.  
  768.    case MODE_BUMP_ENVMAP_ATI:
  769.       /* special - not handled here */
  770.       assert(0);
  771.       return src[0];
  772.    default:
  773.       assert(0);
  774.       return src[0];
  775.    }
  776. }
  777.  
  778. /**
  779.  * Generate instructions for one texture unit's env/combiner mode.
  780.  */
  781. static ir_rvalue *
  782. emit_texenv(texenv_fragment_program *p, GLuint unit)
  783. {
  784.    const struct state_key *key = p->state;
  785.    GLboolean rgb_saturate, alpha_saturate;
  786.    GLuint rgb_shift, alpha_shift;
  787.  
  788.    if (!key->unit[unit].enabled) {
  789.       return get_source(p, SRC_PREVIOUS, 0);
  790.    }
  791.    if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
  792.       /* this isn't really a env stage delivering a color and handled elsewhere */
  793.       return get_source(p, SRC_PREVIOUS, 0);
  794.    }
  795.    
  796.    switch (key->unit[unit].ModeRGB) {
  797.    case MODE_DOT3_RGB_EXT:
  798.       alpha_shift = key->unit[unit].ScaleShiftA;
  799.       rgb_shift = 0;
  800.       break;
  801.    case MODE_DOT3_RGBA_EXT:
  802.       alpha_shift = 0;
  803.       rgb_shift = 0;
  804.       break;
  805.    default:
  806.       rgb_shift = key->unit[unit].ScaleShiftRGB;
  807.       alpha_shift = key->unit[unit].ScaleShiftA;
  808.       break;
  809.    }
  810.    
  811.    /* If we'll do rgb/alpha shifting don't saturate in emit_combine().
  812.     * We don't want to clamp twice.
  813.     */
  814.    if (rgb_shift)
  815.       rgb_saturate = GL_FALSE;  /* saturate after rgb shift */
  816.    else if (need_saturate(key->unit[unit].ModeRGB))
  817.       rgb_saturate = GL_TRUE;
  818.    else
  819.       rgb_saturate = GL_FALSE;
  820.  
  821.    if (alpha_shift)
  822.       alpha_saturate = GL_FALSE;  /* saturate after alpha shift */
  823.    else if (need_saturate(key->unit[unit].ModeA))
  824.       alpha_saturate = GL_TRUE;
  825.    else
  826.       alpha_saturate = GL_FALSE;
  827.  
  828.    ir_variable *temp_var = p->make_temp(glsl_type::vec4_type, "texenv_combine");
  829.    ir_dereference *deref;
  830.    ir_rvalue *val;
  831.  
  832.    /* Emit the RGB and A combine ops
  833.     */
  834.    if (key->unit[unit].ModeRGB == key->unit[unit].ModeA &&
  835.        args_match(key, unit)) {
  836.       val = emit_combine(p, unit,
  837.                          key->unit[unit].NumArgsRGB,
  838.                          key->unit[unit].ModeRGB,
  839.                          key->unit[unit].OptRGB);
  840.       val = smear(p, val);
  841.       if (rgb_saturate)
  842.          val = saturate(val);
  843.  
  844.       p->emit(assign(temp_var, val));
  845.    }
  846.    else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
  847.             key->unit[unit].ModeRGB == MODE_DOT3_RGBA) {
  848.       ir_rvalue *val = emit_combine(p, unit,
  849.                                     key->unit[unit].NumArgsRGB,
  850.                                     key->unit[unit].ModeRGB,
  851.                                     key->unit[unit].OptRGB);
  852.       val = smear(p, val);
  853.       if (rgb_saturate)
  854.          val = saturate(val);
  855.       p->emit(assign(temp_var, val));
  856.    }
  857.    else {
  858.       /* Need to do something to stop from re-emitting identical
  859.        * argument calculations here:
  860.        */
  861.       val = emit_combine(p, unit,
  862.                          key->unit[unit].NumArgsRGB,
  863.                          key->unit[unit].ModeRGB,
  864.                          key->unit[unit].OptRGB);
  865.       val = swizzle_xyz(smear(p, val));
  866.       if (rgb_saturate)
  867.          val = saturate(val);
  868.       p->emit(assign(temp_var, val, WRITEMASK_XYZ));
  869.  
  870.       val = emit_combine(p, unit,
  871.                          key->unit[unit].NumArgsA,
  872.                          key->unit[unit].ModeA,
  873.                          key->unit[unit].OptA);
  874.       val = swizzle_w(smear(p, val));
  875.       if (alpha_saturate)
  876.          val = saturate(val);
  877.       p->emit(assign(temp_var, val, WRITEMASK_W));
  878.    }
  879.  
  880.    deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
  881.  
  882.    /* Deal with the final shift:
  883.     */
  884.    if (alpha_shift || rgb_shift) {
  885.       ir_constant *shift;
  886.  
  887.       if (rgb_shift == alpha_shift) {
  888.          shift = new(p->mem_ctx) ir_constant((float)(1 << rgb_shift));
  889.       }
  890.       else {
  891.          float const_data[4] = {
  892.             float(1 << rgb_shift),
  893.             float(1 << rgb_shift),
  894.             float(1 << rgb_shift),
  895.             float(1 << alpha_shift)
  896.          };
  897.          shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type,
  898.                                              (ir_constant_data *)const_data);
  899.       }
  900.  
  901.       return saturate(mul(deref, shift));
  902.    }
  903.    else
  904.       return deref;
  905. }
  906.  
  907.  
  908. /**
  909.  * Generate instruction for getting a texture source term.
  910.  */
  911. static void load_texture( texenv_fragment_program *p, GLuint unit )
  912. {
  913.    ir_dereference *deref;
  914.  
  915.    if (p->src_texture[unit])
  916.       return;
  917.  
  918.    const GLuint texTarget = p->state->unit[unit].source_index;
  919.    ir_rvalue *texcoord;
  920.  
  921.    if (!(p->state->inputs_available & (VARYING_BIT_TEX0 << unit))) {
  922.       texcoord = get_current_attrib(p, VERT_ATTRIB_TEX0 + unit);
  923.    } else if (p->texcoord_tex[unit]) {
  924.       texcoord = new(p->mem_ctx) ir_dereference_variable(p->texcoord_tex[unit]);
  925.    } else {
  926.       ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord");
  927.       assert(tc_array);
  928.       texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
  929.       ir_rvalue *index = new(p->mem_ctx) ir_constant(unit);
  930.       texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
  931.       tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
  932.    }
  933.  
  934.    if (!p->state->unit[unit].enabled) {
  935.       p->src_texture[unit] = p->make_temp(glsl_type::vec4_type,
  936.                                           "dummy_tex");
  937.       p->emit(p->src_texture[unit]);
  938.  
  939.       p->emit(assign(p->src_texture[unit], new(p->mem_ctx) ir_constant(0.0f)));
  940.       return ;
  941.    }
  942.  
  943.    const glsl_type *sampler_type = NULL;
  944.    int coords = 0;
  945.  
  946.    switch (texTarget) {
  947.    case TEXTURE_1D_INDEX:
  948.       if (p->state->unit[unit].shadow)
  949.          sampler_type = p->shader->symbols->get_type("sampler1DShadow");
  950.       else
  951.          sampler_type = p->shader->symbols->get_type("sampler1D");
  952.       coords = 1;
  953.       break;
  954.    case TEXTURE_1D_ARRAY_INDEX:
  955.       if (p->state->unit[unit].shadow)
  956.          sampler_type = p->shader->symbols->get_type("sampler1DArrayShadow");
  957.       else
  958.          sampler_type = p->shader->symbols->get_type("sampler1DArray");
  959.       coords = 2;
  960.       break;
  961.    case TEXTURE_2D_INDEX:
  962.       if (p->state->unit[unit].shadow)
  963.          sampler_type = p->shader->symbols->get_type("sampler2DShadow");
  964.       else
  965.          sampler_type = p->shader->symbols->get_type("sampler2D");
  966.       coords = 2;
  967.       break;
  968.    case TEXTURE_2D_ARRAY_INDEX:
  969.       if (p->state->unit[unit].shadow)
  970.          sampler_type = p->shader->symbols->get_type("sampler2DArrayShadow");
  971.       else
  972.          sampler_type = p->shader->symbols->get_type("sampler2DArray");
  973.       coords = 3;
  974.       break;
  975.    case TEXTURE_RECT_INDEX:
  976.       if (p->state->unit[unit].shadow)
  977.          sampler_type = p->shader->symbols->get_type("sampler2DRectShadow");
  978.       else
  979.          sampler_type = p->shader->symbols->get_type("sampler2DRect");
  980.       coords = 2;
  981.       break;
  982.    case TEXTURE_3D_INDEX:
  983.       assert(!p->state->unit[unit].shadow);
  984.       sampler_type = p->shader->symbols->get_type("sampler3D");
  985.       coords = 3;
  986.       break;
  987.    case TEXTURE_CUBE_INDEX:
  988.       if (p->state->unit[unit].shadow)
  989.          sampler_type = p->shader->symbols->get_type("samplerCubeShadow");
  990.       else
  991.          sampler_type = p->shader->symbols->get_type("samplerCube");
  992.       coords = 3;
  993.       break;
  994.    case TEXTURE_EXTERNAL_INDEX:
  995.       assert(!p->state->unit[unit].shadow);
  996.       sampler_type = p->shader->symbols->get_type("samplerExternalOES");
  997.       coords = 2;
  998.       break;
  999.    }
  1000.  
  1001.    p->src_texture[unit] = p->make_temp(glsl_type::vec4_type,
  1002.                                        "tex");
  1003.  
  1004.    ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex);
  1005.  
  1006.  
  1007.    char *sampler_name = ralloc_asprintf(p->mem_ctx, "sampler_%d", unit);
  1008.    ir_variable *sampler = new(p->mem_ctx) ir_variable(sampler_type,
  1009.                                                       sampler_name,
  1010.                                                       ir_var_uniform);
  1011.    p->top_instructions->push_head(sampler);
  1012.  
  1013.    /* Set the texture unit for this sampler.  The linker will pick this value
  1014.     * up and do-the-right-thing.
  1015.     *
  1016.     * NOTE: The cast to int is important.  Without it, the constant will have
  1017.     * type uint, and things later on may get confused.
  1018.     */
  1019.    sampler->constant_value = new(p->mem_ctx) ir_constant(int(unit));
  1020.  
  1021.    deref = new(p->mem_ctx) ir_dereference_variable(sampler);
  1022.    tex->set_sampler(deref, glsl_type::vec4_type);
  1023.  
  1024.    tex->coordinate = new(p->mem_ctx) ir_swizzle(texcoord, 0, 1, 2, 3, coords);
  1025.  
  1026.    if (p->state->unit[unit].shadow) {
  1027.       texcoord = texcoord->clone(p->mem_ctx, NULL);
  1028.       tex->shadow_comparitor = new(p->mem_ctx) ir_swizzle(texcoord,
  1029.                                                           coords, 0, 0, 0,
  1030.                                                           1);
  1031.       coords++;
  1032.    }
  1033.  
  1034.    texcoord = texcoord->clone(p->mem_ctx, NULL);
  1035.    tex->projector = swizzle_w(texcoord);
  1036.  
  1037.    p->emit(assign(p->src_texture[unit], tex));
  1038. }
  1039.  
  1040. static void
  1041. load_texenv_source(texenv_fragment_program *p,
  1042.                    GLuint src, GLuint unit)
  1043. {
  1044.    switch (src) {
  1045.    case SRC_TEXTURE:
  1046.       load_texture(p, unit);
  1047.       break;
  1048.  
  1049.    case SRC_TEXTURE0:
  1050.    case SRC_TEXTURE1:
  1051.    case SRC_TEXTURE2:
  1052.    case SRC_TEXTURE3:
  1053.    case SRC_TEXTURE4:
  1054.    case SRC_TEXTURE5:
  1055.    case SRC_TEXTURE6:
  1056.    case SRC_TEXTURE7:      
  1057.       load_texture(p, src - SRC_TEXTURE0);
  1058.       break;
  1059.      
  1060.    default:
  1061.       /* not a texture src - do nothing */
  1062.       break;
  1063.    }
  1064. }
  1065.  
  1066.  
  1067. /**
  1068.  * Generate instructions for loading all texture source terms.
  1069.  */
  1070. static GLboolean
  1071. load_texunit_sources( texenv_fragment_program *p, GLuint unit )
  1072. {
  1073.    const struct state_key *key = p->state;
  1074.    GLuint i;
  1075.  
  1076.    for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
  1077.       load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit );
  1078.    }
  1079.  
  1080.    for (i = 0; i < key->unit[unit].NumArgsA; i++) {
  1081.       load_texenv_source( p, key->unit[unit].OptA[i].Source, unit );
  1082.    }
  1083.  
  1084.    return GL_TRUE;
  1085. }
  1086.  
  1087. /**
  1088.  * Generate instructions for loading bump map textures.
  1089.  */
  1090. static void
  1091. load_texunit_bumpmap( texenv_fragment_program *p, GLuint unit )
  1092. {
  1093.    const struct state_key *key = p->state;
  1094.    GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0;
  1095.    ir_rvalue *bump;
  1096.    ir_rvalue *texcoord;
  1097.    ir_variable *rot_mat_0, *rot_mat_1;
  1098.  
  1099.    rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA");
  1100.    rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA");
  1101.  
  1102.    ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord");
  1103.    assert(tc_array);
  1104.    texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
  1105.    ir_rvalue *index = new(p->mem_ctx) ir_constant(bumpedUnitNr);
  1106.    texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
  1107.    tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
  1108.  
  1109.    load_texenv_source( p, unit + SRC_TEXTURE0, unit );
  1110.  
  1111.    /* Apply rot matrix and add coords to be available in next phase.
  1112.     * dest = Arg1 + (Arg0.xx * rotMat0) + (Arg0.yy * rotMat1)
  1113.     * note only 2 coords are affected the rest are left unchanged (mul by 0)
  1114.     */
  1115.    ir_rvalue *bump_x, *bump_y;
  1116.  
  1117.    texcoord = smear(p, texcoord);
  1118.  
  1119.    /* bump_texcoord = texcoord */
  1120.    ir_variable *bumped = p->make_temp(texcoord->type, "bump_texcoord");
  1121.    p->emit(bumped);
  1122.    p->emit(assign(bumped, texcoord));
  1123.  
  1124.    /* bump_texcoord.xy += arg0.x * rotmat0 + arg0.y * rotmat1 */
  1125.    bump = get_source(p, key->unit[unit].OptRGB[0].Source, unit);
  1126.    bump_x = mul(swizzle_x(bump), rot_mat_0);
  1127.    bump_y = mul(swizzle_y(bump->clone(p->mem_ctx, NULL)), rot_mat_1);
  1128.  
  1129.    p->emit(assign(bumped, add(swizzle_xy(bumped), add(bump_x, bump_y)),
  1130.                   WRITEMASK_XY));
  1131.  
  1132.    p->texcoord_tex[bumpedUnitNr] = bumped;
  1133. }
  1134.  
  1135. /**
  1136.  * Applies the fog calculations.
  1137.  *
  1138.  * This is basically like the ARB_fragment_prorgam fog options.  Note
  1139.  * that ffvertex_prog.c produces fogcoord for us when
  1140.  * GL_FOG_COORDINATE_EXT is set to GL_FRAGMENT_DEPTH_EXT.
  1141.  */
  1142. static ir_rvalue *
  1143. emit_fog_instructions(texenv_fragment_program *p,
  1144.                       ir_rvalue *fragcolor)
  1145. {
  1146.    struct state_key *key = p->state;
  1147.    ir_rvalue *f, *temp;
  1148.    ir_variable *params, *oparams;
  1149.    ir_variable *fogcoord;
  1150.  
  1151.    /* Temporary storage for the whole fog result.  Fog calculations
  1152.     * only affect rgb so we're hanging on to the .a value of fragcolor
  1153.     * this way.
  1154.     */
  1155.    ir_variable *fog_result = p->make_temp(glsl_type::vec4_type, "fog_result");
  1156.    p->emit(assign(fog_result, fragcolor));
  1157.  
  1158.    fragcolor = swizzle_xyz(fog_result);
  1159.  
  1160.    oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA");
  1161.    fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord");
  1162.    params = p->shader->symbols->get_variable("gl_Fog");
  1163.    f = new(p->mem_ctx) ir_dereference_variable(fogcoord);
  1164.  
  1165.    ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor");
  1166.  
  1167.    switch (key->fog_mode) {
  1168.    case FOG_LINEAR:
  1169.       /* f = (end - z) / (end - start)
  1170.        *
  1171.        * gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and
  1172.        * (end / (end - start)) so we can generate a single MAD.
  1173.        */
  1174.       f = add(mul(f, swizzle_x(oparams)), swizzle_y(oparams));
  1175.       break;
  1176.    case FOG_EXP:
  1177.       /* f = e^(-(density * fogcoord))
  1178.        *
  1179.        * gl_MesaFogParamsOptimized gives us density/ln(2) so we can
  1180.        * use EXP2 which is generally the native instruction without
  1181.        * having to do any further math on the fog density uniform.
  1182.        */
  1183.       f = mul(f, swizzle_z(oparams));
  1184.       f = new(p->mem_ctx) ir_expression(ir_unop_neg, f);
  1185.       f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f);
  1186.       break;
  1187.    case FOG_EXP2:
  1188.       /* f = e^(-(density * fogcoord)^2)
  1189.        *
  1190.        * gl_MesaFogParamsOptimized gives us density/sqrt(ln(2)) so we
  1191.        * can do this like FOG_EXP but with a squaring after the
  1192.        * multiply by density.
  1193.        */
  1194.       ir_variable *temp_var = p->make_temp(glsl_type::float_type, "fog_temp");
  1195.       p->emit(assign(temp_var, mul(f, swizzle_w(oparams))));
  1196.  
  1197.       f = mul(temp_var, temp_var);
  1198.       f = new(p->mem_ctx) ir_expression(ir_unop_neg, f);
  1199.       f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f);
  1200.       break;
  1201.    }
  1202.  
  1203.    p->emit(assign(f_var, saturate(f)));
  1204.  
  1205.    f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var);
  1206.    temp = new(p->mem_ctx) ir_dereference_variable(params);
  1207.    temp = new(p->mem_ctx) ir_dereference_record(temp, "color");
  1208.    temp = mul(swizzle_xyz(temp), f);
  1209.  
  1210.    p->emit(assign(fog_result, add(temp, mul(fragcolor, f_var)), WRITEMASK_XYZ));
  1211.  
  1212.    return new(p->mem_ctx) ir_dereference_variable(fog_result);
  1213. }
  1214.  
  1215. static void
  1216. emit_instructions(texenv_fragment_program *p)
  1217. {
  1218.    struct state_key *key = p->state;
  1219.    GLuint unit;
  1220.  
  1221.    if (key->enabled_units) {
  1222.       /* Zeroth pass - bump map textures first */
  1223.       for (unit = 0; unit < key->nr_enabled_units; unit++) {
  1224.          if (key->unit[unit].enabled &&
  1225.              key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
  1226.             load_texunit_bumpmap(p, unit);
  1227.          }
  1228.       }
  1229.  
  1230.       /* First pass - to support texture_env_crossbar, first identify
  1231.        * all referenced texture sources and emit texld instructions
  1232.        * for each:
  1233.        */
  1234.       for (unit = 0; unit < key->nr_enabled_units; unit++)
  1235.          if (key->unit[unit].enabled) {
  1236.             load_texunit_sources(p, unit);
  1237.          }
  1238.  
  1239.       /* Second pass - emit combine instructions to build final color:
  1240.        */
  1241.       for (unit = 0; unit < key->nr_enabled_units; unit++) {
  1242.          if (key->unit[unit].enabled) {
  1243.             p->src_previous = emit_texenv(p, unit);
  1244.          }
  1245.       }
  1246.    }
  1247.  
  1248.    ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0);
  1249.  
  1250.    if (key->separate_specular) {
  1251.       ir_variable *spec_result = p->make_temp(glsl_type::vec4_type,
  1252.                                               "specular_add");
  1253.       p->emit(assign(spec_result, cf));
  1254.  
  1255.       ir_rvalue *secondary;
  1256.       if (p->state->inputs_available & VARYING_BIT_COL1) {
  1257.          ir_variable *var =
  1258.             p->shader->symbols->get_variable("gl_SecondaryColor");
  1259.          assert(var);
  1260.          secondary = swizzle_xyz(var);
  1261.       } else {
  1262.          secondary = swizzle_xyz(get_current_attrib(p, VERT_ATTRIB_COLOR1));
  1263.       }
  1264.  
  1265.       p->emit(assign(spec_result, add(swizzle_xyz(spec_result), secondary),
  1266.                      WRITEMASK_XYZ));
  1267.  
  1268.       cf = new(p->mem_ctx) ir_dereference_variable(spec_result);
  1269.    }
  1270.  
  1271.    if (key->fog_enabled) {
  1272.       cf = emit_fog_instructions(p, cf);
  1273.    }
  1274.  
  1275.    ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor");
  1276.    assert(frag_color);
  1277.    p->emit(assign(frag_color, cf));
  1278. }
  1279.  
  1280. /**
  1281.  * Generate a new fragment program which implements the context's
  1282.  * current texture env/combine mode.
  1283.  */
  1284. static struct gl_shader_program *
  1285. create_new_program(struct gl_context *ctx, struct state_key *key)
  1286. {
  1287.    texenv_fragment_program p;
  1288.    unsigned int unit;
  1289.    _mesa_glsl_parse_state *state;
  1290.  
  1291.    p.mem_ctx = ralloc_context(NULL);
  1292.    p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER);
  1293.    p.shader->ir = new(p.shader) exec_list;
  1294.    state = new(p.shader) _mesa_glsl_parse_state(ctx, GL_FRAGMENT_SHADER,
  1295.                                                 p.shader);
  1296.    p.shader->symbols = state->symbols;
  1297.    p.top_instructions = p.shader->ir;
  1298.    p.instructions = p.shader->ir;
  1299.    p.state = key;
  1300.    p.shader_program = ctx->Driver.NewShaderProgram(ctx, 0);
  1301.  
  1302.    /* Tell the linker to ignore the fact that we're building a
  1303.     * separate shader, in case we're in a GLES2 context that would
  1304.     * normally reject that.  The real problem is that we're building a
  1305.     * fixed function program in a GLES2 context at all, but that's a
  1306.     * big mess to clean up.
  1307.     */
  1308.    p.shader_program->InternalSeparateShader = GL_TRUE;
  1309.  
  1310.    state->language_version = 130;
  1311.    state->es_shader = false;
  1312.    if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external)
  1313.       state->OES_EGL_image_external_enable = true;
  1314.    _mesa_glsl_initialize_types(state);
  1315.    _mesa_glsl_initialize_variables(p.instructions, state);
  1316.  
  1317.    for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
  1318.       p.src_texture[unit] = NULL;
  1319.       p.texcoord_tex[unit] = NULL;
  1320.    }
  1321.  
  1322.    p.src_previous = NULL;
  1323.  
  1324.    ir_function *main_f = new(p.mem_ctx) ir_function("main");
  1325.    p.emit(main_f);
  1326.    state->symbols->add_function(main_f);
  1327.  
  1328.    ir_function_signature *main_sig =
  1329.       new(p.mem_ctx) ir_function_signature(p.shader->symbols->get_type("void"));
  1330.    main_sig->is_defined = true;
  1331.    main_f->add_signature(main_sig);
  1332.  
  1333.    p.instructions = &main_sig->body;
  1334.    if (key->num_draw_buffers)
  1335.       emit_instructions(&p);
  1336.  
  1337.    validate_ir_tree(p.shader->ir);
  1338.  
  1339.    const struct gl_shader_compiler_options *options =
  1340.       &ctx->ShaderCompilerOptions[MESA_SHADER_FRAGMENT];
  1341.  
  1342.    while (do_common_optimization(p.shader->ir, false, false, 32, options))
  1343.       ;
  1344.    reparent_ir(p.shader->ir, p.shader->ir);
  1345.  
  1346.    p.shader->CompileStatus = true;
  1347.    p.shader->Version = state->language_version;
  1348.    p.shader->num_builtins_to_link = state->num_builtins_to_link;
  1349.    p.shader_program->Shaders =
  1350.       (gl_shader **)malloc(sizeof(*p.shader_program->Shaders));
  1351.    p.shader_program->Shaders[0] = p.shader;
  1352.    p.shader_program->NumShaders = 1;
  1353.  
  1354.    _mesa_glsl_link_shader(ctx, p.shader_program);
  1355.  
  1356.    if (!p.shader_program->LinkStatus)
  1357.       _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n",
  1358.                     p.shader_program->InfoLog);
  1359.  
  1360.    ralloc_free(p.mem_ctx);
  1361.    return p.shader_program;
  1362. }
  1363.  
  1364. extern "C" {
  1365.  
  1366. /**
  1367.  * Return a fragment program which implements the current
  1368.  * fixed-function texture, fog and color-sum operations.
  1369.  */
  1370. struct gl_shader_program *
  1371. _mesa_get_fixed_func_fragment_program(struct gl_context *ctx)
  1372. {
  1373.    struct gl_shader_program *shader_program;
  1374.    struct state_key key;
  1375.    GLuint keySize;
  1376.  
  1377.    keySize = make_state_key(ctx, &key);
  1378.  
  1379.    shader_program = (struct gl_shader_program *)
  1380.       _mesa_search_program_cache(ctx->FragmentProgram.Cache,
  1381.                                  &key, keySize);
  1382.  
  1383.    if (!shader_program) {
  1384.       shader_program = create_new_program(ctx, &key);
  1385.  
  1386.       _mesa_shader_cache_insert(ctx, ctx->FragmentProgram.Cache,
  1387.                                 &key, keySize, shader_program);
  1388.    }
  1389.  
  1390.    return shader_program;
  1391. }
  1392.  
  1393. }
  1394.