1 typedef unsigned char GLboolean;
2 typedef unsigned int GLbitfield;
3 typedef unsigned int GLuint;
5 typedef struct __GLcontextRec GLcontext;
6 struct gl_texture_attrib {
9 PROGRAM_TEMPORARY = 0, PROGRAM_LOCAL_PARAM = 1, PROGRAM_ENV_PARAM =
10 2, PROGRAM_STATE_VAR = 3, PROGRAM_INPUT = 4, PROGRAM_OUTPUT =
11 5, PROGRAM_NAMED_PARAM = 6, PROGRAM_CONSTANT = 7, PROGRAM_UNIFORM =
12 8, PROGRAM_VARYING = 9, PROGRAM_WRITE_ONLY = 10, PROGRAM_ADDRESS =
13 11, PROGRAM_SAMPLER = 12, PROGRAM_UNDEFINED = 13, PROGRAM_FILE_MAX
15 struct gl_fragment_program_state {
17 struct gl_fragment_program *_TexEnvProgram;
19 struct gl_shader_state {
20 struct gl_shader_program *CurrentProgram;
23 GLuint MaxTextureUnits;
25 struct __GLcontextRec {
26 struct gl_constants Const;
27 struct gl_fragment_program_state FragmentProgram;
28 struct gl_shader_state Shader;
30 typedef enum prog_opcode {
32 0, OPCODE_ABS, OPCODE_ADD, OPCODE_ARA, OPCODE_ARL, OPCODE_ARL_NV,
33 OPCODE_ARR, OPCODE_BGNLOOP, OPCODE_BGNSUB, OPCODE_BRA, OPCODE_BRK,
34 OPCODE_CAL, OPCODE_CMP, OPCODE_CONT, OPCODE_COS, OPCODE_DDX,
35 OPCODE_DDY, OPCODE_DP3, OPCODE_DP4, OPCODE_DPH, OPCODE_DST,
36 OPCODE_ELSE, OPCODE_END, OPCODE_ENDIF, OPCODE_ENDLOOP,
37 OPCODE_ENDSUB, OPCODE_EX2, OPCODE_EXP, OPCODE_FLR, OPCODE_FRC,
38 OPCODE_IF, OPCODE_INT, OPCODE_KIL, OPCODE_KIL_NV, OPCODE_LG2,
39 OPCODE_LIT, OPCODE_LOG, OPCODE_LRP, OPCODE_MAD, OPCODE_MAX,
40 OPCODE_MIN, OPCODE_MOV, OPCODE_MUL, OPCODE_NOISE1, OPCODE_NOISE2,
41 OPCODE_NOISE3, OPCODE_NOISE4, OPCODE_PK2H, OPCODE_PK2US,
42 OPCODE_PK4B, OPCODE_PK4UB, OPCODE_POW, OPCODE_POPA, OPCODE_PRINT,
43 OPCODE_PUSHA, OPCODE_RCC, OPCODE_RCP, OPCODE_RET, OPCODE_RFL,
44 OPCODE_RSQ, OPCODE_SCS, OPCODE_SEQ, OPCODE_SFL, OPCODE_SGE,
45 OPCODE_SGT, OPCODE_SIN, OPCODE_SLE, OPCODE_SLT, OPCODE_SNE,
46 OPCODE_SSG, OPCODE_STR, OPCODE_SUB, OPCODE_SWZ, OPCODE_TEX,
47 OPCODE_TXB, OPCODE_TXD, OPCODE_TXL, OPCODE_TXP, OPCODE_TXP_NV,
48 OPCODE_UP2H, OPCODE_UP2US, OPCODE_UP4B, OPCODE_UP4UB, OPCODE_X2D,
49 OPCODE_XPD, MAX_OPCODE
56 GLbitfield enabled_units;
60 struct mode_opt OptRGB[3];
68 static const struct ureg undef = {
69 PROGRAM_UNDEFINED, ~0, 0, 0, 0, 0, 0
71 struct texenv_fragment_program {
72 struct state_key *state;
73 struct ureg src_texture[8];
74 struct ureg src_previous;
75 GLuint last_tex_stage;
77 static struct ureg get_temp(struct texenv_fragment_program *p)
80 static struct ureg register_const4f(struct texenv_fragment_program *p,
81 GLfloat s0, GLfloat s1, GLfloat s2,
85 static struct ureg emit_combine_source(struct texenv_fragment_program *p,
86 GLuint mask, GLuint unit, GLuint source,
90 static struct ureg emit_combine(struct texenv_fragment_program *p,
91 struct ureg dest, GLuint mask,
92 GLboolean saturate, GLuint unit, GLuint nr,
93 GLuint mode, const struct mode_opt *opt)
97 for (i = 0; i < nr; i++)
99 emit_combine_source(p, mask, unit, opt[i].Source,
106 struct ureg tmp0 = get_temp(p);
107 struct ureg neg1 = register_const4f(p, -1, -1, -1, -1);
108 struct ureg two = register_const4f(p, 2, 2, 2, 2);
109 emit_arith(p, OPCODE_MAD, tmp0, 0xf, 0, two, src[0],
114 static struct ureg emit_texenv(struct texenv_fragment_program *p, GLuint unit)
116 struct state_key *key = p->state;
117 GLboolean saturate = (unit < p->last_tex_stage);
118 struct ureg out, shift;
120 if (key->unit[unit].ModeRGB == key->unit[unit].ModeA
121 && args_match(key, unit)) {
123 emit_combine(p, dest, 0xf, saturate, unit,
124 key->unit[unit].NumArgsRGB,
125 key->unit[unit].ModeRGB,
126 key->unit[unit].OptRGB);
129 static void create_new_program(GLcontext * ctx, struct state_key *key,
130 struct gl_fragment_program *program)
132 struct texenv_fragment_program p;
134 for (unit = 0; unit < 8; unit++)
135 p.src_texture[unit] = undef;
136 if (key->enabled_units) {
137 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++)
138 if (key->enabled_units & (1 << unit)) {
139 p.src_previous = emit_texenv(&p, unit);
143 void _mesa_UpdateTexEnvProgram(GLcontext * ctx)
145 struct state_key key;
146 if (!ctx->FragmentProgram._Enabled && !ctx->Shader.CurrentProgram) {
147 if (!ctx->FragmentProgram._TexEnvProgram) {
148 create_new_program(ctx, &key,
149 ctx->FragmentProgram._TexEnvProgram);