#include "s_texture.h"
+#ifdef USE_TCC
+
/* UREG - a way of representing an FP source register including
* swizzling and negation in a single GLuint. Major flaw is the
* limitiation to source->Index < 32. Secondary flaw is the fact that
va_list ap;
va_start( ap, fmt );
- p->c_strlen += vsnprintf( p->c_str + p->c_strlen,
- sizeof(p->c_str) - p->c_strlen,
- fmt, ap );
+ if (p->c_strlen < sizeof(p->c_str))
+ p->c_strlen += vsnprintf( p->c_str + p->c_strlen,
+ sizeof(p->c_str) - p->c_strlen,
+ fmt, ap );
va_end( ap );
}
static INLINE void emit_char( struct fragment_program *p, char c )
{
- if (p->c_strlen < sizeof(p->c_str))
+ if (p->c_strlen < sizeof(p->c_str)) {
p->c_str[p->c_strlen] = c;
-
- p->c_strlen++;
+ p->c_strlen++;
+ }
}
{
emit(p, "\n\n\n");
+ /* Mesa's program_parameter struct:
+ */
+ emit(p,
+ "struct program_parameter\n"
+ "{\n"
+ " const char *Name;\n"
+ " int Type;\n"
+ " int StateIndexes[6];\n"
+ " float Values[4];\n"
+ "};\n");
+
+
/* Texture samplers, not written yet:
*/
emit(p, "extern void TEX( void *ctx, const float *txc, int unit, float *rslt );\n"
/* The usual macros, not really needed, but handy:
*/
emit(p, "#define MIN2(x,y) ((x)<(y)?(x):(y))\n"
- "#define MAX2(x,y) ((x)<(y)?(x):(y))\n");
+ "#define MAX2(x,y) ((x)<(y)?(x):(y))\n"
+ "#define SATURATE(x) ((x)>1.0?1.0:((x)<0.0?0.0:(x)))\n");
/* Our function!
*/
- emit(p, "void run_program( void *ctx, \n"
+ emit(p, "int run_program( void *ctx, \n"
" const float (*local_param)[4], \n"
" const float (*env_param)[4], \n"
- " const float (*state_param)[4], \n"
+ " const struct program_parameter *state_param, \n"
" const float (*interp)[4], \n"
" float (*outputs)[4])\n"
"{\n"
static void print_footer( struct fragment_program *p )
{
+ emit(p, " return 1;");
emit(p, "}\n");
}
case UREG_TYPE_INTERP: emit(p, "interp"); break;
case UREG_TYPE_LOCAL_CONST: emit(p, "local_const"); break;
case UREG_TYPE_ENV_CONST: emit(p, "env_const"); break;
- case UREG_TYPE_STATE_CONST: emit(p, "state_const"); break;
+ case UREG_TYPE_STATE_CONST: emit(p, "state_param"); break;
case UREG_TYPE_PARAM: emit(p, "param"); break;
};
emit(p, "[%d]", GET_UREG_NR(arg));
+
+ if (GET_UREG_TYPE(arg) == UREG_TYPE_STATE_CONST) {
+ emit(p, ".Values");
+ }
}
return;
}
- if (GET_UREG_TYPE(arg) == UREG_TYPE_STATE_CONST) {
+ if (GET_UREG_TYPE(arg) == UREG_TYPE_STATE_CONST &&
+ p->Parameters->Parameters[GET_UREG_NR(arg)].Type == CONSTANT) {
emit(p, "%g", p->Parameters->Parameters[GET_UREG_NR(arg)].Values[src]);
return;
}
emit(p, ";\n");
}
+static void do_tex_kill( struct fragment_program *p,
+ const struct fp_instruction *inst,
+ GLuint arg )
+{
+ GLuint i;
+
+ emit(p, "if (");
+
+ for (i = 0; i < 4; i++) {
+ print_arg( p, deref(arg, i) );
+ emit(p, " < 0 ");
+ if (i + 1 < 4)
+ emit(p, "|| ");
+ }
+
+ emit(p, ")\n");
+ emit(p, " return 0;\n");
+
+}
+
static void do_tex_simple( struct fragment_program *p,
const struct fp_instruction *inst,
const char *fn, GLuint texunit, GLuint arg )
{
emit(p, " ");
print_dest(p, inst, i);
- emit(p, " = CLAMPF( ");
+ emit(p, " = SATURATE( ");
print_dest(p, inst, i);
- emit(p, ", 0.0, 1.0);\n");
+ emit(p, ");\n");
}
static void assign_single( GLuint i,
break;
case FP_OPCODE_KIL:
- /* TODO */
+ do_tex_kill(p, inst, src[0]);
break;
case FP_OPCODE_LG2:
print_header( p );
translate_program( p );
print_footer( p );
- emit_char(p, 0);
-
- printf("C program length: %d/%d chars\n", p->c_strlen, strlen(p->c_str));
- printf(p->c_str);
}
}
+#endif /*USE_TCC*/