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