typedef unsigned char GLboolean; typedef unsigned int GLbitfield; typedef unsigned int GLuint; typedef float GLfloat; typedef struct __GLcontextRec GLcontext; struct gl_texture_attrib { }; enum register_file { PROGRAM_TEMPORARY = 0, PROGRAM_LOCAL_PARAM = 1, PROGRAM_ENV_PARAM = 2, PROGRAM_STATE_VAR = 3, PROGRAM_INPUT = 4, PROGRAM_OUTPUT = 5, PROGRAM_NAMED_PARAM = 6, PROGRAM_CONSTANT = 7, PROGRAM_UNIFORM = 8, PROGRAM_VARYING = 9, PROGRAM_WRITE_ONLY = 10, PROGRAM_ADDRESS = 11, PROGRAM_SAMPLER = 12, PROGRAM_UNDEFINED = 13, PROGRAM_FILE_MAX }; struct gl_fragment_program_state { GLboolean _Enabled; struct gl_fragment_program *_TexEnvProgram; }; struct gl_shader_state { struct gl_shader_program *CurrentProgram; }; struct gl_constants { GLuint MaxTextureUnits; } GLvertexformat; struct __GLcontextRec { struct gl_constants Const; struct gl_fragment_program_state FragmentProgram; struct gl_shader_state Shader; }; typedef enum prog_opcode { OPCODE_NOP = 0, OPCODE_ABS, OPCODE_ADD, OPCODE_ARA, OPCODE_ARL, OPCODE_ARL_NV, OPCODE_ARR, OPCODE_BGNLOOP, OPCODE_BGNSUB, OPCODE_BRA, OPCODE_BRK, OPCODE_CAL, OPCODE_CMP, OPCODE_CONT, OPCODE_COS, OPCODE_DDX, OPCODE_DDY, OPCODE_DP3, OPCODE_DP4, OPCODE_DPH, OPCODE_DST, OPCODE_ELSE, OPCODE_END, OPCODE_ENDIF, OPCODE_ENDLOOP, OPCODE_ENDSUB, OPCODE_EX2, OPCODE_EXP, OPCODE_FLR, OPCODE_FRC, OPCODE_IF, OPCODE_INT, OPCODE_KIL, OPCODE_KIL_NV, OPCODE_LG2, OPCODE_LIT, OPCODE_LOG, OPCODE_LRP, OPCODE_MAD, OPCODE_MAX, OPCODE_MIN, OPCODE_MOV, OPCODE_MUL, OPCODE_NOISE1, OPCODE_NOISE2, OPCODE_NOISE3, OPCODE_NOISE4, OPCODE_PK2H, OPCODE_PK2US, OPCODE_PK4B, OPCODE_PK4UB, OPCODE_POW, OPCODE_POPA, OPCODE_PRINT, OPCODE_PUSHA, OPCODE_RCC, OPCODE_RCP, OPCODE_RET, OPCODE_RFL, OPCODE_RSQ, OPCODE_SCS, OPCODE_SEQ, OPCODE_SFL, OPCODE_SGE, OPCODE_SGT, OPCODE_SIN, OPCODE_SLE, OPCODE_SLT, OPCODE_SNE, OPCODE_SSG, OPCODE_STR, OPCODE_SUB, OPCODE_SWZ, OPCODE_TEX, OPCODE_TXB, OPCODE_TXD, OPCODE_TXL, OPCODE_TXP, OPCODE_TXP_NV, OPCODE_UP2H, OPCODE_UP2US, OPCODE_UP4B, OPCODE_UP4UB, OPCODE_X2D, OPCODE_XPD, MAX_OPCODE } gl_inst_opcode; struct mode_opt { GLuint Source:4; GLuint Operand:3; }; struct state_key { GLbitfield enabled_units; struct { GLuint NumArgsRGB:2; GLuint ModeRGB:4; struct mode_opt OptRGB[3]; GLuint ModeA:4; } unit[8]; }; struct ureg { GLuint file:4; GLuint idx:8; }; static const struct ureg undef = { PROGRAM_UNDEFINED, ~0, 0, 0, 0, 0, 0 }; struct texenv_fragment_program { struct state_key *state; struct ureg src_texture[8]; struct ureg src_previous; GLuint last_tex_stage; }; static struct ureg get_temp(struct texenv_fragment_program *p) { } static struct ureg register_const4f(struct texenv_fragment_program *p, GLfloat s0, GLfloat s1, GLfloat s2, GLfloat s3) { } static struct ureg emit_combine_source(struct texenv_fragment_program *p, GLuint mask, GLuint unit, GLuint source, GLuint operand) { } static struct ureg emit_combine(struct texenv_fragment_program *p, struct ureg dest, GLuint mask, GLboolean saturate, GLuint unit, GLuint nr, GLuint mode, const struct mode_opt *opt) { struct ureg src[3]; GLuint i; for (i = 0; i < nr; i++) src[i] = emit_combine_source(p, mask, unit, opt[i].Source, opt[i].Operand); switch (mode) { case 8: case 9: case 7: case 6:{ struct ureg tmp0 = get_temp(p); struct ureg neg1 = register_const4f(p, -1, -1, -1, -1); struct ureg two = register_const4f(p, 2, 2, 2, 2); emit_arith(p, OPCODE_MAD, tmp0, 0xf, 0, two, src[0], neg1); } } } static struct ureg emit_texenv(struct texenv_fragment_program *p, GLuint unit) { struct state_key *key = p->state; GLboolean saturate = (unit < p->last_tex_stage); struct ureg out, shift; struct ureg dest; if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && args_match(key, unit)) { out = emit_combine(p, dest, 0xf, saturate, unit, key->unit[unit].NumArgsRGB, key->unit[unit].ModeRGB, key->unit[unit].OptRGB); } } static void create_new_program(GLcontext * ctx, struct state_key *key, struct gl_fragment_program *program) { struct texenv_fragment_program p; GLuint unit; for (unit = 0; unit < 8; unit++) p.src_texture[unit] = undef; if (key->enabled_units) { for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) if (key->enabled_units & (1 << unit)) { p.src_previous = emit_texenv(&p, unit); } } } void _mesa_UpdateTexEnvProgram(GLcontext * ctx) { struct state_key key; if (!ctx->FragmentProgram._Enabled && !ctx->Shader.CurrentProgram) { if (!ctx->FragmentProgram._TexEnvProgram) { create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram); } } }