Home | History | Annotate | Download | only in main
      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/uniforms.h"
     35 #include "main/macros.h"
     36 #include "main/samplerobj.h"
     37 #include "program/program.h"
     38 #include "program/prog_parameter.h"
     39 #include "program/prog_cache.h"
     40 #include "program/prog_instruction.h"
     41 #include "program/prog_print.h"
     42 #include "program/prog_statevars.h"
     43 #include "program/programopt.h"
     44 #include "texenvprogram.h"
     45 }
     46 #include "main/uniforms.h"
     47 #include "../glsl/glsl_types.h"
     48 #include "../glsl/ir.h"
     49 #include "../glsl/ir_builder.h"
     50 #include "../glsl/glsl_symbol_table.h"
     51 #include "../glsl/glsl_parser_extras.h"
     52 #include "../glsl/ir_optimization.h"
     53 #include "../glsl/ir_print_visitor.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 #define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0)
    308 
    309 /**
    310  * Identify all possible varying inputs.  The fragment program will
    311  * never reference non-varying inputs, but will track them via state
    312  * constants instead.
    313  *
    314  * This function figures out all the inputs that the fragment program
    315  * has access to.  The bitmask is later reduced to just those which
    316  * are actually referenced.
    317  */
    318 static GLbitfield get_fp_input_mask( struct gl_context *ctx )
    319 {
    320    /* _NEW_PROGRAM */
    321    const GLboolean vertexShader =
    322       (ctx->Shader.CurrentVertexProgram &&
    323        ctx->Shader.CurrentVertexProgram->LinkStatus &&
    324        ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]);
    325    const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
    326    GLbitfield fp_inputs = 0x0;
    327 
    328    if (ctx->VertexProgram._Overriden) {
    329       /* Somebody's messing with the vertex program and we don't have
    330        * a clue what's happening.  Assume that it could be producing
    331        * all possible outputs.
    332        */
    333       fp_inputs = ~0;
    334    }
    335    else if (ctx->RenderMode == GL_FEEDBACK) {
    336       /* _NEW_RENDERMODE */
    337       fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0);
    338    }
    339    else if (!(vertexProgram || vertexShader)) {
    340       /* Fixed function vertex logic */
    341       /* _NEW_VARYING_VP_INPUTS */
    342       GLbitfield64 varying_inputs = ctx->varying_vp_inputs;
    343 
    344       /* These get generated in the setup routine regardless of the
    345        * vertex program:
    346        */
    347       /* _NEW_POINT */
    348       if (ctx->Point.PointSprite)
    349          varying_inputs |= FRAG_BITS_TEX_ANY;
    350 
    351       /* First look at what values may be computed by the generated
    352        * vertex program:
    353        */
    354       /* _NEW_LIGHT */
    355       if (ctx->Light.Enabled) {
    356          fp_inputs |= FRAG_BIT_COL0;
    357 
    358          if (texenv_doing_secondary_color(ctx))
    359             fp_inputs |= FRAG_BIT_COL1;
    360       }
    361 
    362       /* _NEW_TEXTURE */
    363       fp_inputs |= (ctx->Texture._TexGenEnabled |
    364                     ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0;
    365 
    366       /* Then look at what might be varying as a result of enabled
    367        * arrays, etc:
    368        */
    369       if (varying_inputs & VERT_BIT_COLOR0)
    370          fp_inputs |= FRAG_BIT_COL0;
    371       if (varying_inputs & VERT_BIT_COLOR1)
    372          fp_inputs |= FRAG_BIT_COL1;
    373 
    374       fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0)
    375                     << FRAG_ATTRIB_TEX0);
    376 
    377    }
    378    else {
    379       /* calculate from vp->outputs */
    380       struct gl_program *vprog;
    381       GLbitfield64 vp_outputs;
    382 
    383       /* Choose GLSL vertex shader over ARB vertex program.  Need this
    384        * since vertex shader state validation comes after fragment state
    385        * validation (see additional comments in state.c).
    386        */
    387       if (vertexShader)
    388          vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
    389       else
    390          vprog = &ctx->VertexProgram.Current->Base;
    391 
    392       vp_outputs = vprog->OutputsWritten;
    393 
    394       /* These get generated in the setup routine regardless of the
    395        * vertex program:
    396        */
    397       /* _NEW_POINT */
    398       if (ctx->Point.PointSprite)
    399          vp_outputs |= FRAG_BITS_TEX_ANY;
    400 
    401       if (vp_outputs & (1 << VERT_RESULT_COL0))
    402          fp_inputs |= FRAG_BIT_COL0;
    403       if (vp_outputs & (1 << VERT_RESULT_COL1))
    404          fp_inputs |= FRAG_BIT_COL1;
    405 
    406       fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0)
    407                     << FRAG_ATTRIB_TEX0);
    408    }
    409 
    410    return fp_inputs;
    411 }
    412 
    413 
    414 /**
    415  * Examine current texture environment state and generate a unique
    416  * key to identify it.
    417  */
    418 static GLuint make_state_key( struct gl_context *ctx,  struct state_key *key )
    419 {
    420    GLuint i, j;
    421    GLbitfield inputs_referenced = FRAG_BIT_COL0;
    422    const GLbitfield inputs_available = get_fp_input_mask( ctx );
    423    GLuint keySize;
    424 
    425    memset(key, 0, sizeof(*key));
    426 
    427    /* _NEW_TEXTURE */
    428    for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
    429       const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
    430       const struct gl_texture_object *texObj = texUnit->_Current;
    431       const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine;
    432       const struct gl_sampler_object *samp;
    433       GLenum format;
    434 
    435       if (!texUnit->_ReallyEnabled || !texUnit->Enabled)
    436          continue;
    437 
    438       samp = _mesa_get_samplerobj(ctx, i);
    439       format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
    440 
    441       key->unit[i].enabled = 1;
    442       key->enabled_units |= (1<<i);
    443       key->nr_enabled_units = i + 1;
    444       inputs_referenced |= FRAG_BIT_TEX(i);
    445 
    446       key->unit[i].source_index =
    447          translate_tex_src_bit(texUnit->_ReallyEnabled);
    448 
    449       key->unit[i].shadow =
    450          ((samp->CompareMode == GL_COMPARE_R_TO_TEXTURE) &&
    451           ((format == GL_DEPTH_COMPONENT) ||
    452            (format == GL_DEPTH_STENCIL_EXT)));
    453 
    454       key->unit[i].NumArgsRGB = comb->_NumArgsRGB;
    455       key->unit[i].NumArgsA = comb->_NumArgsA;
    456 
    457       key->unit[i].ModeRGB =
    458 	 translate_mode(texUnit->EnvMode, comb->ModeRGB);
    459       key->unit[i].ModeA =
    460 	 translate_mode(texUnit->EnvMode, comb->ModeA);
    461 
    462       key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB;
    463       key->unit[i].ScaleShiftA = comb->ScaleShiftA;
    464 
    465       for (j = 0; j < MAX_COMBINER_TERMS; j++) {
    466          key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]);
    467          key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]);
    468          key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]);
    469          key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]);
    470       }
    471 
    472       if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
    473          /* requires some special translation */
    474          key->unit[i].NumArgsRGB = 2;
    475          key->unit[i].ScaleShiftRGB = 0;
    476          key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR;
    477          key->unit[i].OptRGB[0].Source = SRC_TEXTURE;
    478          key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR;
    479          key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0;
    480        }
    481    }
    482 
    483    /* _NEW_LIGHT | _NEW_FOG */
    484    if (texenv_doing_secondary_color(ctx)) {
    485       key->separate_specular = 1;
    486       inputs_referenced |= FRAG_BIT_COL1;
    487    }
    488 
    489    /* _NEW_FOG */
    490    if (ctx->Fog.Enabled) {
    491       key->fog_enabled = 1;
    492       key->fog_mode = translate_fog_mode(ctx->Fog.Mode);
    493       inputs_referenced |= FRAG_BIT_FOGC; /* maybe */
    494    }
    495 
    496    /* _NEW_BUFFERS */
    497    key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
    498 
    499    /* _NEW_COLOR */
    500    if (ctx->Color.AlphaEnabled && key->num_draw_buffers == 0) {
    501       /* if alpha test is enabled we need to emit at least one color */
    502       key->num_draw_buffers = 1;
    503    }
    504 
    505    key->inputs_available = (inputs_available & inputs_referenced);
    506 
    507    /* compute size of state key, ignoring unused texture units */
    508    keySize = sizeof(*key) - sizeof(key->unit)
    509       + key->nr_enabled_units * sizeof(key->unit[0]);
    510 
    511    return keySize;
    512 }
    513 
    514 
    515 /** State used to build the fragment program:
    516  */
    517 class texenv_fragment_program : public ir_factory {
    518 public:
    519    struct gl_shader_program *shader_program;
    520    struct gl_shader *shader;
    521    exec_list *top_instructions;
    522    struct state_key *state;
    523 
    524    ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS];
    525    /* Reg containing each texture unit's sampled texture color,
    526     * else undef.
    527     */
    528 
    529    /* Texcoord override from bumpmapping. */
    530    ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS];
    531 
    532    /* Reg containing texcoord for a texture unit,
    533     * needed for bump mapping, else undef.
    534     */
    535 
    536    ir_rvalue *src_previous;	/**< Reg containing color from previous
    537 				 * stage.  May need to be decl'd.
    538 				 */
    539 };
    540 
    541 static ir_rvalue *
    542 get_current_attrib(struct texenv_fragment_program *p, GLuint attrib)
    543 {
    544    ir_variable *current;
    545    ir_rvalue *val;
    546 
    547    current = p->shader->symbols->get_variable("gl_CurrentAttribFragMESA");
    548    current->max_array_access = MAX2(current->max_array_access, attrib);
    549    val = new(p->mem_ctx) ir_dereference_variable(current);
    550    ir_rvalue *index = new(p->mem_ctx) ir_constant(attrib);
    551    return new(p->mem_ctx) ir_dereference_array(val, index);
    552 }
    553 
    554 static ir_rvalue *
    555 get_gl_Color(struct texenv_fragment_program *p)
    556 {
    557    if (p->state->inputs_available & FRAG_BIT_COL0) {
    558       ir_variable *var = p->shader->symbols->get_variable("gl_Color");
    559       assert(var);
    560       return new(p->mem_ctx) ir_dereference_variable(var);
    561    } else {
    562       return get_current_attrib(p, VERT_ATTRIB_COLOR0);
    563    }
    564 }
    565 
    566 static ir_rvalue *
    567 get_source(struct texenv_fragment_program *p,
    568 	   GLuint src, GLuint unit)
    569 {
    570    ir_variable *var;
    571    ir_dereference *deref;
    572 
    573    switch (src) {
    574    case SRC_TEXTURE:
    575       return new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]);
    576 
    577    case SRC_TEXTURE0:
    578    case SRC_TEXTURE1:
    579    case SRC_TEXTURE2:
    580    case SRC_TEXTURE3:
    581    case SRC_TEXTURE4:
    582    case SRC_TEXTURE5:
    583    case SRC_TEXTURE6:
    584    case SRC_TEXTURE7:
    585       return new(p->mem_ctx)
    586 	 ir_dereference_variable(p->src_texture[src - SRC_TEXTURE0]);
    587 
    588    case SRC_CONSTANT:
    589       var = p->shader->symbols->get_variable("gl_TextureEnvColor");
    590       assert(var);
    591       deref = new(p->mem_ctx) ir_dereference_variable(var);
    592       var->max_array_access = MAX2(var->max_array_access, unit);
    593       return new(p->mem_ctx) ir_dereference_array(deref,
    594 						  new(p->mem_ctx) ir_constant(unit));
    595 
    596    case SRC_PRIMARY_COLOR:
    597       var = p->shader->symbols->get_variable("gl_Color");
    598       assert(var);
    599       return new(p->mem_ctx) ir_dereference_variable(var);
    600 
    601    case SRC_ZERO:
    602       return new(p->mem_ctx) ir_constant(0.0f);
    603 
    604    case SRC_PREVIOUS:
    605       if (!p->src_previous) {
    606 	 return get_gl_Color(p);
    607       } else {
    608 	 return p->src_previous->clone(p->mem_ctx, NULL);
    609       }
    610 
    611    default:
    612       assert(0);
    613       return NULL;
    614    }
    615 }
    616 
    617 static ir_rvalue *
    618 emit_combine_source(struct texenv_fragment_program *p,
    619 		    GLuint unit,
    620 		    GLuint source,
    621 		    GLuint operand)
    622 {
    623    ir_rvalue *src;
    624 
    625    src = get_source(p, source, unit);
    626 
    627    switch (operand) {
    628    case OPR_ONE_MINUS_SRC_COLOR:
    629       return sub(new(p->mem_ctx) ir_constant(1.0f), src);
    630 
    631    case OPR_SRC_ALPHA:
    632       return src->type->is_scalar() ? src : swizzle_w(src);
    633 
    634    case OPR_ONE_MINUS_SRC_ALPHA: {
    635       ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src);
    636 
    637       return sub(new(p->mem_ctx) ir_constant(1.0f), scalar);
    638    }
    639 
    640    case OPR_ZERO:
    641       return new(p->mem_ctx) ir_constant(0.0f);
    642    case OPR_ONE:
    643       return new(p->mem_ctx) ir_constant(1.0f);
    644    case OPR_SRC_COLOR:
    645       return src;
    646    default:
    647       assert(0);
    648       return src;
    649    }
    650 }
    651 
    652 /**
    653  * Check if the RGB and Alpha sources and operands match for the given
    654  * texture unit's combinder state.  When the RGB and A sources and
    655  * operands match, we can emit fewer instructions.
    656  */
    657 static GLboolean args_match( const struct state_key *key, GLuint unit )
    658 {
    659    GLuint i, numArgs = key->unit[unit].NumArgsRGB;
    660 
    661    for (i = 0; i < numArgs; i++) {
    662       if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source)
    663 	 return GL_FALSE;
    664 
    665       switch (key->unit[unit].OptA[i].Operand) {
    666       case OPR_SRC_ALPHA:
    667 	 switch (key->unit[unit].OptRGB[i].Operand) {
    668 	 case OPR_SRC_COLOR:
    669 	 case OPR_SRC_ALPHA:
    670 	    break;
    671 	 default:
    672 	    return GL_FALSE;
    673 	 }
    674 	 break;
    675       case OPR_ONE_MINUS_SRC_ALPHA:
    676 	 switch (key->unit[unit].OptRGB[i].Operand) {
    677 	 case OPR_ONE_MINUS_SRC_COLOR:
    678 	 case OPR_ONE_MINUS_SRC_ALPHA:
    679 	    break;
    680 	 default:
    681 	    return GL_FALSE;
    682 	 }
    683 	 break;
    684       default:
    685 	 return GL_FALSE;	/* impossible */
    686       }
    687    }
    688 
    689    return GL_TRUE;
    690 }
    691 
    692 static ir_rvalue *
    693 smear(struct texenv_fragment_program *p, ir_rvalue *val)
    694 {
    695    if (!val->type->is_scalar())
    696       return val;
    697 
    698    return swizzle_xxxx(val);
    699 }
    700 
    701 static ir_rvalue *
    702 emit_combine(struct texenv_fragment_program *p,
    703 	     GLuint unit,
    704 	     GLuint nr,
    705 	     GLuint mode,
    706 	     const struct mode_opt *opt)
    707 {
    708    ir_rvalue *src[MAX_COMBINER_TERMS];
    709    ir_rvalue *tmp0, *tmp1;
    710    GLuint i;
    711 
    712    assert(nr <= MAX_COMBINER_TERMS);
    713 
    714    for (i = 0; i < nr; i++)
    715       src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand );
    716 
    717    switch (mode) {
    718    case MODE_REPLACE:
    719       return src[0];
    720 
    721    case MODE_MODULATE:
    722       return mul(src[0], src[1]);
    723 
    724    case MODE_ADD:
    725       return add(src[0], src[1]);
    726 
    727    case MODE_ADD_SIGNED:
    728       return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f));
    729 
    730    case MODE_INTERPOLATE:
    731       /* Arg0 * (Arg2) + Arg1 * (1-Arg2) */
    732       tmp0 = mul(src[0], src[2]);
    733       tmp1 = mul(src[1], sub(new(p->mem_ctx) ir_constant(1.0f),
    734 			     src[2]->clone(p->mem_ctx, NULL)));
    735       return add(tmp0, tmp1);
    736 
    737    case MODE_SUBTRACT:
    738       return sub(src[0], src[1]);
    739 
    740    case MODE_DOT3_RGBA:
    741    case MODE_DOT3_RGBA_EXT:
    742    case MODE_DOT3_RGB_EXT:
    743    case MODE_DOT3_RGB: {
    744       tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f));
    745       tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f));
    746 
    747       tmp1 = mul(src[1], new(p->mem_ctx) ir_constant(2.0f));
    748       tmp1 = add(tmp1, new(p->mem_ctx) ir_constant(-1.0f));
    749 
    750       return dot(swizzle_xyz(smear(p, tmp0)), swizzle_xyz(smear(p, tmp1)));
    751    }
    752    case MODE_MODULATE_ADD_ATI:
    753       return add(mul(src[0], src[2]), src[1]);
    754 
    755    case MODE_MODULATE_SIGNED_ADD_ATI:
    756       return add(add(mul(src[0], src[2]), src[1]),
    757 		 new(p->mem_ctx) ir_constant(-0.5f));
    758 
    759    case MODE_MODULATE_SUBTRACT_ATI:
    760       return sub(mul(src[0], src[2]), src[1]);
    761 
    762    case MODE_ADD_PRODUCTS:
    763       return add(mul(src[0], src[1]), mul(src[2], src[3]));
    764 
    765    case MODE_ADD_PRODUCTS_SIGNED:
    766       return add(add(mul(src[0], src[1]), mul(src[2], src[3])),
    767 		 new(p->mem_ctx) ir_constant(-0.5f));
    768 
    769    case MODE_BUMP_ENVMAP_ATI:
    770       /* special - not handled here */
    771       assert(0);
    772       return src[0];
    773    default:
    774       assert(0);
    775       return src[0];
    776    }
    777 }
    778 
    779 /**
    780  * Generate instructions for one texture unit's env/combiner mode.
    781  */
    782 static ir_rvalue *
    783 emit_texenv(struct texenv_fragment_program *p, GLuint unit)
    784 {
    785    const struct state_key *key = p->state;
    786    GLboolean rgb_saturate, alpha_saturate;
    787    GLuint rgb_shift, alpha_shift;
    788 
    789    if (!key->unit[unit].enabled) {
    790       return get_source(p, SRC_PREVIOUS, 0);
    791    }
    792    if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
    793       /* this isn't really a env stage delivering a color and handled elsewhere */
    794       return get_source(p, SRC_PREVIOUS, 0);
    795    }
    796 
    797    switch (key->unit[unit].ModeRGB) {
    798    case MODE_DOT3_RGB_EXT:
    799       alpha_shift = key->unit[unit].ScaleShiftA;
    800       rgb_shift = 0;
    801       break;
    802    case MODE_DOT3_RGBA_EXT:
    803       alpha_shift = 0;
    804       rgb_shift = 0;
    805       break;
    806    default:
    807       rgb_shift = key->unit[unit].ScaleShiftRGB;
    808       alpha_shift = key->unit[unit].ScaleShiftA;
    809       break;
    810    }
    811 
    812    /* If we'll do rgb/alpha shifting don't saturate in emit_combine().
    813     * We don't want to clamp twice.
    814     */
    815    if (rgb_shift)
    816       rgb_saturate = GL_FALSE;  /* saturate after rgb shift */
    817    else if (need_saturate(key->unit[unit].ModeRGB))
    818       rgb_saturate = GL_TRUE;
    819    else
    820       rgb_saturate = GL_FALSE;
    821 
    822    if (alpha_shift)
    823       alpha_saturate = GL_FALSE;  /* saturate after alpha shift */
    824    else if (need_saturate(key->unit[unit].ModeA))
    825       alpha_saturate = GL_TRUE;
    826    else
    827       alpha_saturate = GL_FALSE;
    828 
    829    ir_variable *temp_var = p->make_temp(glsl_type::vec4_type, "texenv_combine");
    830    ir_dereference *deref;
    831    ir_rvalue *val;
    832 
    833    /* Emit the RGB and A combine ops
    834     */
    835    if (key->unit[unit].ModeRGB == key->unit[unit].ModeA &&
    836        args_match(key, unit)) {
    837       val = emit_combine(p, unit,
    838 			 key->unit[unit].NumArgsRGB,
    839 			 key->unit[unit].ModeRGB,
    840 			 key->unit[unit].OptRGB);
    841       val = smear(p, val);
    842       if (rgb_saturate)
    843 	 val = saturate(val);
    844 
    845       p->emit(assign(temp_var, val));
    846    }
    847    else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
    848 	    key->unit[unit].ModeRGB == MODE_DOT3_RGBA) {
    849       ir_rvalue *val = emit_combine(p, unit,
    850 				    key->unit[unit].NumArgsRGB,
    851 				    key->unit[unit].ModeRGB,
    852 				    key->unit[unit].OptRGB);
    853       val = smear(p, val);
    854       if (rgb_saturate)
    855 	 val = saturate(val);
    856       p->emit(assign(temp_var, val));
    857    }
    858    else {
    859       /* Need to do something to stop from re-emitting identical
    860        * argument calculations here:
    861        */
    862       val = emit_combine(p, unit,
    863 			 key->unit[unit].NumArgsRGB,
    864 			 key->unit[unit].ModeRGB,
    865 			 key->unit[unit].OptRGB);
    866       val = swizzle_xyz(smear(p, val));
    867       if (rgb_saturate)
    868 	 val = saturate(val);
    869       p->emit(assign(temp_var, val, WRITEMASK_XYZ));
    870 
    871       val = emit_combine(p, unit,
    872 			 key->unit[unit].NumArgsA,
    873 			 key->unit[unit].ModeA,
    874 			 key->unit[unit].OptA);
    875       val = swizzle_w(smear(p, val));
    876       if (alpha_saturate)
    877 	 val = saturate(val);
    878       p->emit(assign(temp_var, val, WRITEMASK_W));
    879    }
    880 
    881    deref = new(p->mem_ctx) ir_dereference_variable(temp_var);
    882 
    883    /* Deal with the final shift:
    884     */
    885    if (alpha_shift || rgb_shift) {
    886       ir_constant *shift;
    887 
    888       if (rgb_shift == alpha_shift) {
    889 	 shift = new(p->mem_ctx) ir_constant((float)(1 << rgb_shift));
    890       }
    891       else {
    892 	 float const_data[4] = {
    893 	    1 << rgb_shift,
    894 	    1 << rgb_shift,
    895 	    1 << rgb_shift,
    896 	    1 << alpha_shift
    897 	 };
    898 	 shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type,
    899 					     (ir_constant_data *)const_data);
    900       }
    901 
    902       return saturate(mul(deref, shift));
    903    }
    904    else
    905       return deref;
    906 }
    907 
    908 
    909 /**
    910  * Generate instruction for getting a texture source term.
    911  */
    912 static void load_texture( struct texenv_fragment_program *p, GLuint unit )
    913 {
    914    ir_dereference *deref;
    915 
    916    if (p->src_texture[unit])
    917       return;
    918 
    919    const GLuint texTarget = p->state->unit[unit].source_index;
    920    ir_rvalue *texcoord;
    921 
    922    if (!(p->state->inputs_available & (FRAG_BIT_TEX0 << unit))) {
    923       texcoord = get_current_attrib(p, VERT_ATTRIB_TEX0 + unit);
    924    } else if (p->texcoord_tex[unit]) {
    925       texcoord = new(p->mem_ctx) ir_dereference_variable(p->texcoord_tex[unit]);
    926    } else {
    927       ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord");
    928       assert(tc_array);
    929       texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
    930       ir_rvalue *index = new(p->mem_ctx) ir_constant(unit);
    931       texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
    932       tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
    933    }
    934 
    935    if (!p->state->unit[unit].enabled) {
    936       p->src_texture[unit] = p->make_temp(glsl_type::vec4_type,
    937 					  "dummy_tex");
    938       p->emit(p->src_texture[unit]);
    939 
    940       p->emit(assign(p->src_texture[unit], new(p->mem_ctx) ir_constant(0.0f)));
    941       return ;
    942    }
    943 
    944    const glsl_type *sampler_type = NULL;
    945    int coords = 0;
    946 
    947    switch (texTarget) {
    948    case TEXTURE_1D_INDEX:
    949       if (p->state->unit[unit].shadow)
    950 	 sampler_type = p->shader->symbols->get_type("sampler1DShadow");
    951       else
    952 	 sampler_type = p->shader->symbols->get_type("sampler1D");
    953       coords = 1;
    954       break;
    955    case TEXTURE_1D_ARRAY_INDEX:
    956       if (p->state->unit[unit].shadow)
    957 	 sampler_type = p->shader->symbols->get_type("sampler1DArrayShadow");
    958       else
    959 	 sampler_type = p->shader->symbols->get_type("sampler1DArray");
    960       coords = 2;
    961       break;
    962    case TEXTURE_2D_INDEX:
    963       if (p->state->unit[unit].shadow)
    964 	 sampler_type = p->shader->symbols->get_type("sampler2DShadow");
    965       else
    966 	 sampler_type = p->shader->symbols->get_type("sampler2D");
    967       coords = 2;
    968       break;
    969    case TEXTURE_2D_ARRAY_INDEX:
    970       if (p->state->unit[unit].shadow)
    971 	 sampler_type = p->shader->symbols->get_type("sampler2DArrayShadow");
    972       else
    973 	 sampler_type = p->shader->symbols->get_type("sampler2DArray");
    974       coords = 3;
    975       break;
    976    case TEXTURE_RECT_INDEX:
    977       if (p->state->unit[unit].shadow)
    978 	 sampler_type = p->shader->symbols->get_type("sampler2DRectShadow");
    979       else
    980 	 sampler_type = p->shader->symbols->get_type("sampler2DRect");
    981       coords = 2;
    982       break;
    983    case TEXTURE_3D_INDEX:
    984       assert(!p->state->unit[unit].shadow);
    985       sampler_type = p->shader->symbols->get_type("sampler3D");
    986       coords = 3;
    987       break;
    988    case TEXTURE_CUBE_INDEX:
    989       if (p->state->unit[unit].shadow)
    990 	 sampler_type = p->shader->symbols->get_type("samplerCubeShadow");
    991       else
    992 	 sampler_type = p->shader->symbols->get_type("samplerCube");
    993       coords = 3;
    994       break;
    995    case TEXTURE_EXTERNAL_INDEX:
    996       assert(!p->state->unit[unit].shadow);
    997       sampler_type = p->shader->symbols->get_type("samplerExternalOES");
    998       coords = 2;
    999       break;
   1000    }
   1001 
   1002    p->src_texture[unit] = p->make_temp(glsl_type::vec4_type,
   1003 				       "tex");
   1004 
   1005    ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex);
   1006 
   1007 
   1008    char *sampler_name = ralloc_asprintf(p->mem_ctx, "sampler_%d", unit);
   1009    ir_variable *sampler = new(p->mem_ctx) ir_variable(sampler_type,
   1010 						      sampler_name,
   1011 						      ir_var_uniform);
   1012    p->top_instructions->push_head(sampler);
   1013 
   1014    /* Set the texture unit for this sampler.  The linker will pick this value
   1015     * up and do-the-right-thing.
   1016     *
   1017     * NOTE: The cast to int is important.  Without it, the constant will have
   1018     * type uint, and things later on may get confused.
   1019     */
   1020    sampler->constant_value = new(p->mem_ctx) ir_constant(int(unit));
   1021 
   1022    deref = new(p->mem_ctx) ir_dereference_variable(sampler);
   1023    tex->set_sampler(deref, glsl_type::vec4_type);
   1024 
   1025    tex->coordinate = new(p->mem_ctx) ir_swizzle(texcoord, 0, 1, 2, 3, coords);
   1026 
   1027    if (p->state->unit[unit].shadow) {
   1028       texcoord = texcoord->clone(p->mem_ctx, NULL);
   1029       tex->shadow_comparitor = new(p->mem_ctx) ir_swizzle(texcoord,
   1030 							  coords, 0, 0, 0,
   1031 							  1);
   1032       coords++;
   1033    }
   1034 
   1035    texcoord = texcoord->clone(p->mem_ctx, NULL);
   1036    tex->projector = swizzle_w(texcoord);
   1037 
   1038    p->emit(assign(p->src_texture[unit], tex));
   1039 }
   1040 
   1041 static void
   1042 load_texenv_source(struct texenv_fragment_program *p,
   1043 		   GLuint src, GLuint unit)
   1044 {
   1045    switch (src) {
   1046    case SRC_TEXTURE:
   1047       load_texture(p, unit);
   1048       break;
   1049 
   1050    case SRC_TEXTURE0:
   1051    case SRC_TEXTURE1:
   1052    case SRC_TEXTURE2:
   1053    case SRC_TEXTURE3:
   1054    case SRC_TEXTURE4:
   1055    case SRC_TEXTURE5:
   1056    case SRC_TEXTURE6:
   1057    case SRC_TEXTURE7:
   1058       load_texture(p, src - SRC_TEXTURE0);
   1059       break;
   1060 
   1061    default:
   1062       /* not a texture src - do nothing */
   1063       break;
   1064    }
   1065 }
   1066 
   1067 
   1068 /**
   1069  * Generate instructions for loading all texture source terms.
   1070  */
   1071 static GLboolean
   1072 load_texunit_sources( struct texenv_fragment_program *p, GLuint unit )
   1073 {
   1074    const struct state_key *key = p->state;
   1075    GLuint i;
   1076 
   1077    for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
   1078       load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit );
   1079    }
   1080 
   1081    for (i = 0; i < key->unit[unit].NumArgsA; i++) {
   1082       load_texenv_source( p, key->unit[unit].OptA[i].Source, unit );
   1083    }
   1084 
   1085    return GL_TRUE;
   1086 }
   1087 
   1088 /**
   1089  * Generate instructions for loading bump map textures.
   1090  */
   1091 static void
   1092 load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
   1093 {
   1094    const struct state_key *key = p->state;
   1095    GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0;
   1096    ir_rvalue *bump;
   1097    ir_rvalue *texcoord;
   1098    ir_variable *rot_mat_0, *rot_mat_1;
   1099 
   1100    rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA");
   1101    rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA");
   1102 
   1103    ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord");
   1104    assert(tc_array);
   1105    texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
   1106    ir_rvalue *index = new(p->mem_ctx) ir_constant(bumpedUnitNr);
   1107    texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
   1108    tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
   1109 
   1110    load_texenv_source( p, unit + SRC_TEXTURE0, unit );
   1111 
   1112    /* Apply rot matrix and add coords to be available in next phase.
   1113     * dest = Arg1 + (Arg0.xx * rotMat0) + (Arg0.yy * rotMat1)
   1114     * note only 2 coords are affected the rest are left unchanged (mul by 0)
   1115     */
   1116    ir_rvalue *bump_x, *bump_y;
   1117 
   1118    texcoord = smear(p, texcoord);
   1119 
   1120    /* bump_texcoord = texcoord */
   1121    ir_variable *bumped = p->make_temp(texcoord->type, "bump_texcoord");
   1122    p->emit(bumped);
   1123    p->emit(assign(bumped, texcoord));
   1124 
   1125    /* bump_texcoord.xy += arg0.x * rotmat0 + arg0.y * rotmat1 */
   1126    bump = get_source(p, key->unit[unit].OptRGB[0].Source, unit);
   1127    bump_x = mul(swizzle_x(bump), rot_mat_0);
   1128    bump_y = mul(swizzle_y(bump->clone(p->mem_ctx, NULL)), rot_mat_1);
   1129 
   1130    p->emit(assign(bumped, add(swizzle_xy(bumped), add(bump_x, bump_y)),
   1131 		  WRITEMASK_XY));
   1132 
   1133    p->texcoord_tex[bumpedUnitNr] = bumped;
   1134 }
   1135 
   1136 /**
   1137  * Applies the fog calculations.
   1138  *
   1139  * This is basically like the ARB_fragment_prorgam fog options.  Note
   1140  * that ffvertex_prog.c produces fogcoord for us when
   1141  * GL_FOG_COORDINATE_EXT is set to GL_FRAGMENT_DEPTH_EXT.
   1142  */
   1143 static ir_rvalue *
   1144 emit_fog_instructions(struct texenv_fragment_program *p,
   1145 		      ir_rvalue *fragcolor)
   1146 {
   1147    struct state_key *key = p->state;
   1148    ir_rvalue *f, *temp;
   1149    ir_variable *params, *oparams;
   1150    ir_variable *fogcoord;
   1151 
   1152    /* Temporary storage for the whole fog result.  Fog calculations
   1153     * only affect rgb so we're hanging on to the .a value of fragcolor
   1154     * this way.
   1155     */
   1156    ir_variable *fog_result = p->make_temp(glsl_type::vec4_type, "fog_result");
   1157    p->emit(assign(fog_result, fragcolor));
   1158 
   1159    fragcolor = swizzle_xyz(fog_result);
   1160 
   1161    oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA");
   1162    fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord");
   1163    params = p->shader->symbols->get_variable("gl_Fog");
   1164    f = new(p->mem_ctx) ir_dereference_variable(fogcoord);
   1165 
   1166    ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor");
   1167 
   1168    switch (key->fog_mode) {
   1169    case FOG_LINEAR:
   1170       /* f = (end - z) / (end - start)
   1171        *
   1172        * gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and
   1173        * (end / (end - start)) so we can generate a single MAD.
   1174        */
   1175       f = add(mul(f, swizzle_x(oparams)), swizzle_y(oparams));
   1176       break;
   1177    case FOG_EXP:
   1178       /* f = e^(-(density * fogcoord))
   1179        *
   1180        * gl_MesaFogParamsOptimized gives us density/ln(2) so we can
   1181        * use EXP2 which is generally the native instruction without
   1182        * having to do any further math on the fog density uniform.
   1183        */
   1184       f = mul(f, swizzle_z(oparams));
   1185       f = new(p->mem_ctx) ir_expression(ir_unop_neg, f);
   1186       f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f);
   1187       break;
   1188    case FOG_EXP2:
   1189       /* f = e^(-(density * fogcoord)^2)
   1190        *
   1191        * gl_MesaFogParamsOptimized gives us density/sqrt(ln(2)) so we
   1192        * can do this like FOG_EXP but with a squaring after the
   1193        * multiply by density.
   1194        */
   1195       ir_variable *temp_var = p->make_temp(glsl_type::float_type, "fog_temp");
   1196       p->emit(assign(temp_var, mul(f, swizzle_w(oparams))));
   1197 
   1198       f = mul(temp_var, temp_var);
   1199       f = new(p->mem_ctx) ir_expression(ir_unop_neg, f);
   1200       f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f);
   1201       break;
   1202    }
   1203 
   1204    p->emit(assign(f_var, saturate(f)));
   1205 
   1206    f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var);
   1207    temp = new(p->mem_ctx) ir_dereference_variable(params);
   1208    temp = new(p->mem_ctx) ir_dereference_record(temp, "color");
   1209    temp = mul(swizzle_xyz(temp), f);
   1210 
   1211    p->emit(assign(fog_result, add(temp, mul(fragcolor, f_var)), WRITEMASK_XYZ));
   1212 
   1213    return new(p->mem_ctx) ir_dereference_variable(fog_result);
   1214 }
   1215 
   1216 static void
   1217 emit_instructions(struct texenv_fragment_program *p)
   1218 {
   1219    struct state_key *key = p->state;
   1220    GLuint unit;
   1221 
   1222    if (key->enabled_units) {
   1223       /* Zeroth pass - bump map textures first */
   1224       for (unit = 0; unit < key->nr_enabled_units; unit++) {
   1225 	 if (key->unit[unit].enabled &&
   1226              key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
   1227 	    load_texunit_bumpmap(p, unit);
   1228 	 }
   1229       }
   1230 
   1231       /* First pass - to support texture_env_crossbar, first identify
   1232        * all referenced texture sources and emit texld instructions
   1233        * for each:
   1234        */
   1235       for (unit = 0; unit < key->nr_enabled_units; unit++)
   1236 	 if (key->unit[unit].enabled) {
   1237 	    load_texunit_sources(p, unit);
   1238 	 }
   1239 
   1240       /* Second pass - emit combine instructions to build final color:
   1241        */
   1242       for (unit = 0; unit < key->nr_enabled_units; unit++) {
   1243 	 if (key->unit[unit].enabled) {
   1244 	    p->src_previous = emit_texenv(p, unit);
   1245 	 }
   1246       }
   1247    }
   1248 
   1249    ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0);
   1250 
   1251    if (key->separate_specular) {
   1252       ir_variable *spec_result = p->make_temp(glsl_type::vec4_type,
   1253 					      "specular_add");
   1254       p->emit(assign(spec_result, cf));
   1255 
   1256       ir_rvalue *secondary;
   1257       if (p->state->inputs_available & FRAG_BIT_COL1) {
   1258 	 ir_variable *var =
   1259 	    p->shader->symbols->get_variable("gl_SecondaryColor");
   1260 	 assert(var);
   1261 	 secondary = swizzle_xyz(var);
   1262       } else {
   1263 	 secondary = swizzle_xyz(get_current_attrib(p, VERT_ATTRIB_COLOR1));
   1264       }
   1265 
   1266       p->emit(assign(spec_result, add(swizzle_xyz(spec_result), secondary),
   1267 		     WRITEMASK_XYZ));
   1268 
   1269       cf = new(p->mem_ctx) ir_dereference_variable(spec_result);
   1270    }
   1271 
   1272    if (key->fog_enabled) {
   1273       cf = emit_fog_instructions(p, cf);
   1274    }
   1275 
   1276    ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor");
   1277    assert(frag_color);
   1278    p->emit(assign(frag_color, cf));
   1279 }
   1280 
   1281 /**
   1282  * Generate a new fragment program which implements the context's
   1283  * current texture env/combine mode.
   1284  */
   1285 static struct gl_shader_program *
   1286 create_new_program(struct gl_context *ctx, struct state_key *key)
   1287 {
   1288    texenv_fragment_program p;
   1289    unsigned int unit;
   1290    _mesa_glsl_parse_state *state;
   1291 
   1292    p.mem_ctx = ralloc_context(NULL);
   1293    p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER);
   1294    p.shader->ir = new(p.shader) exec_list;
   1295    state = new(p.shader) _mesa_glsl_parse_state(ctx, GL_FRAGMENT_SHADER,
   1296 						p.shader);
   1297    p.shader->symbols = state->symbols;
   1298    p.top_instructions = p.shader->ir;
   1299    p.instructions = p.shader->ir;
   1300    p.state = key;
   1301    p.shader_program = ctx->Driver.NewShaderProgram(ctx, 0);
   1302 
   1303    /* Tell the linker to ignore the fact that we're building a
   1304     * separate shader, in case we're in a GLES2 context that would
   1305     * normally reject that.  The real problem is that we're building a
   1306     * fixed function program in a GLES2 context at all, but that's a
   1307     * big mess to clean up.
   1308     */
   1309    p.shader_program->InternalSeparateShader = GL_TRUE;
   1310 
   1311    state->language_version = 130;
   1312    if (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    while (do_common_optimization(p.shader->ir, false, false, 32))
   1340       ;
   1341    reparent_ir(p.shader->ir, p.shader->ir);
   1342 
   1343    p.shader->CompileStatus = true;
   1344    p.shader->Version = state->language_version;
   1345    p.shader->num_builtins_to_link = state->num_builtins_to_link;
   1346    p.shader_program->Shaders =
   1347       (gl_shader **)malloc(sizeof(*p.shader_program->Shaders));
   1348    p.shader_program->Shaders[0] = p.shader;
   1349    p.shader_program->NumShaders = 1;
   1350 
   1351    _mesa_glsl_link_shader(ctx, p.shader_program);
   1352 
   1353    /* Set the sampler uniforms, and relink to get them into the linked
   1354     * program.
   1355     */
   1356    struct gl_shader *const fs =
   1357       p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT];
   1358    struct gl_program *const fp = fs->Program;
   1359 
   1360    _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs,
   1361 					       fp->Parameters);
   1362 
   1363    _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters);
   1364 
   1365    _mesa_update_shader_textures_used(p.shader_program, fp);
   1366    if (ctx->Driver.SamplerUniformChange)
   1367       ctx->Driver.SamplerUniformChange(ctx, fp->Target, fp);
   1368 
   1369    if (!p.shader_program->LinkStatus)
   1370       _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n",
   1371 		    p.shader_program->InfoLog);
   1372 
   1373    ralloc_free(p.mem_ctx);
   1374    return p.shader_program;
   1375 }
   1376 
   1377 extern "C" {
   1378 
   1379 /**
   1380  * Return a fragment program which implements the current
   1381  * fixed-function texture, fog and color-sum operations.
   1382  */
   1383 struct gl_shader_program *
   1384 _mesa_get_fixed_func_fragment_program(struct gl_context *ctx)
   1385 {
   1386    struct gl_shader_program *shader_program;
   1387    struct state_key key;
   1388    GLuint keySize;
   1389 
   1390    keySize = make_state_key(ctx, &key);
   1391 
   1392    shader_program = (struct gl_shader_program *)
   1393       _mesa_search_program_cache(ctx->FragmentProgram.Cache,
   1394                                  &key, keySize);
   1395 
   1396    if (!shader_program) {
   1397       shader_program = create_new_program(ctx, &key);
   1398 
   1399       _mesa_shader_cache_insert(ctx, ctx->FragmentProgram.Cache,
   1400 				&key, keySize, shader_program);
   1401    }
   1402 
   1403    return shader_program;
   1404 }
   1405 
   1406 }
   1407