1 struct gl_fragment_program_state {
2 unsigned char _Enabled;
3 struct gl_fragment_program *_TexEnvProgram;
5 struct gl_shader_state {
6 struct gl_shader_program *CurrentProgram;
9 unsigned int MaxTextureUnits;
12 struct gl_constants Const;
13 struct gl_fragment_program_state FragmentProgram;
14 struct gl_shader_state Shader;
17 unsigned int Source:4;
18 unsigned int Operand:3;
21 unsigned int enabled_units;
23 unsigned int NumArgsRGB:2;
24 unsigned int ModeRGB:4;
25 struct mode_opt OptRGB[3];
33 static const struct ureg undef = {
36 struct texenv_fragment_program {
37 struct state_key *state;
38 struct ureg src_texture[8];
39 struct ureg src_previous;
40 unsigned int last_tex_stage;
42 static struct ureg get_temp(struct texenv_fragment_program *p)
45 static struct ureg register_const4f(struct texenv_fragment_program *p,
46 float s0, float s1, float s2,
50 static struct ureg emit_combine_source(struct texenv_fragment_program *p,
51 unsigned int mask, unsigned int unit, unsigned int source,
55 static struct ureg emit_combine(struct texenv_fragment_program *p,
56 struct ureg dest, unsigned int mask,
57 unsigned char saturate, unsigned int unit, unsigned int nr,
58 unsigned int mode, const struct mode_opt *opt)
62 for (i = 0; i < nr; i++)
64 emit_combine_source(p, mask, unit, opt[i].Source,
71 neg1 = register_const4f(p, -1, -1, -1, -1);
72 two = register_const4f(p, 2, 2, 2, 2);
73 emit_arith(p, 0, tmp0, 0xf, 0, two, src[0],
78 static struct ureg emit_texenv(struct texenv_fragment_program *p, unsigned int unit)
80 struct state_key *key;
81 unsigned char saturate;
86 saturate = (unit < p->last_tex_stage);
87 if (key->unit[unit].ModeRGB == key->unit[unit].ModeA
88 && args_match(key, unit))
90 emit_combine(p, dest, 0xf, saturate, unit,
91 key->unit[unit].NumArgsRGB,
92 key->unit[unit].ModeRGB,
93 key->unit[unit].OptRGB);
95 static void create_new_program(GLcontext * ctx, struct state_key *key,
96 struct gl_fragment_program *program)
98 struct texenv_fragment_program p;
100 for (unit = 0; unit < 8; unit++)
101 p.src_texture[unit] = undef;
102 if (key->enabled_units)
103 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++)
104 if (key->enabled_units & (1 << unit))
105 p.src_previous = emit_texenv(&p, unit);
107 void _mesa_UpdateTexEnvProgram(GLcontext * ctx)
109 struct state_key key;
110 if (!ctx->FragmentProgram._Enabled && !ctx->Shader.CurrentProgram)
111 if (!ctx->FragmentProgram._TexEnvProgram)
112 create_new_program(ctx, &key,
113 ctx->FragmentProgram._TexEnvProgram);