📄 s_fragprog_to_c.c
字号:
need_result = GL_TRUE;
if (is_swizzled(arg))
need_tex = GL_TRUE;
if (!need_tex && !need_result) {
do_tex_simple( p, inst, fn, texunit, arg );
return;
}
emit(p, " {\n");
emit(p, " float texcoord[4];\n");
emit(p, " float result[4];\n");
for (i = 0; i < 4; i++) {
emit(p, " texcoord[%d] = ", i);
print_arg( p, deref(arg, i) );
emit(p, ";\n");
}
emit(p, " %s( ctx, texcoord, %d, result);\n", fn, texunit );
for (i = 0; i < 4; i++) {
if (inst->DstReg.WriteMask[i]) {
emit(p, " ");
print_dest(p, inst, i);
emit(p, " = result[%d];\n", i);
}
}
emit(p, " }\n");
}
static void saturate( struct fragment_program *p,
const struct fp_instruction *inst,
GLuint i )
{
emit(p, " ");
print_dest(p, inst, i);
emit(p, " = SATURATE( ");
print_dest(p, inst, i);
emit(p, ");\n");
}
static void assign_single( GLuint i,
struct fragment_program *p,
const struct fp_instruction *inst,
const char *fmt,
... )
{
va_list ap;
va_start( ap, fmt );
if (inst->DstReg.WriteMask[i]) {
emit(p, " ");
print_dest(p, inst, i);
emit(p, " = ");
print_expression( p, i, fmt, ap);
if (inst->Saturate)
saturate(p, inst, i);
}
va_end( ap );
}
static void assign4( struct fragment_program *p,
const struct fp_instruction *inst,
const char *fmt,
... )
{
GLuint i;
va_list ap;
va_start( ap, fmt );
for (i = 0; i < 4; i++)
if (inst->DstReg.WriteMask[i]) {
emit(p, " ");
print_dest(p, inst, i);
emit(p, " = ");
print_expression( p, i, fmt, ap);
if (inst->Saturate)
saturate(p, inst, i);
}
va_end( ap );
}
static void assign4_replicate( struct fragment_program *p,
const struct fp_instruction *inst,
const char *fmt,
... )
{
GLuint i, first = 0;
GLboolean ok = 0;
va_list ap;
for (i = 0; i < 4; i++)
if (inst->DstReg.WriteMask[i]) {
ok = 1;
first = i;
break;
}
if (!ok) return;
va_start( ap, fmt );
emit(p, " ");
print_dest(p, inst, first);
emit(p, " = ");
print_expression( p, 0, fmt, ap);
if (inst->Saturate)
saturate(p, inst, first);
va_end( ap );
for (i = first+1; i < 4; i++)
if (inst->DstReg.WriteMask[i]) {
emit(p, " ");
print_dest(p, inst, i);
emit(p, " = ");
print_dest(p, inst, first);
emit(p, ";\n");
}
}
static GLuint nr_args( GLuint opcode )
{
switch (opcode) {
case FP_OPCODE_ABS: return 1;
case FP_OPCODE_ADD: return 2;
case FP_OPCODE_CMP: return 3;
case FP_OPCODE_COS: return 1;
case FP_OPCODE_DP3: return 2;
case FP_OPCODE_DP4: return 2;
case FP_OPCODE_DPH: return 2;
case FP_OPCODE_DST: return 2;
case FP_OPCODE_EX2: return 1;
case FP_OPCODE_FLR: return 1;
case FP_OPCODE_FRC: return 1;
case FP_OPCODE_KIL: return 1;
case FP_OPCODE_LG2: return 1;
case FP_OPCODE_LIT: return 1;
case FP_OPCODE_LRP: return 3;
case FP_OPCODE_MAD: return 3;
case FP_OPCODE_MAX: return 2;
case FP_OPCODE_MIN: return 2;
case FP_OPCODE_MOV: return 1;
case FP_OPCODE_MUL: return 2;
case FP_OPCODE_POW: return 2;
case FP_OPCODE_RCP: return 1;
case FP_OPCODE_RSQ: return 1;
case FP_OPCODE_SCS: return 1;
case FP_OPCODE_SGE: return 2;
case FP_OPCODE_SIN: return 1;
case FP_OPCODE_SLT: return 2;
case FP_OPCODE_SUB: return 2;
case FP_OPCODE_SWZ: return 1;
case FP_OPCODE_TEX: return 1;
case FP_OPCODE_TXB: return 1;
case FP_OPCODE_TXP: return 1;
case FP_OPCODE_XPD: return 2;
default: return 0;
}
}
static void translate_program( struct fragment_program *p )
{
const struct fp_instruction *inst = p->Instructions;
for (; inst->Opcode != FP_OPCODE_END; inst++) {
GLuint src[3], i;
GLuint nr = nr_args( inst->Opcode );
for (i = 0; i < nr; i++)
src[i] = src_vector( &inst->SrcReg[i] );
/* Print the original program instruction string */
if (p->Base.String)
{
const char *s = (const char *) p->Base.String + inst->StringPos;
emit(p, " /* ");
while (*s != ';') {
emit_char(p, *s);
s++;
}
emit(p, "; */\n");
}
switch (inst->Opcode) {
case FP_OPCODE_ABS:
assign4(p, inst, "fabsf(%s)", src[0]);
break;
case FP_OPCODE_ADD:
assign4(p, inst, "%s + %s", src[0], src[1]);
break;
case FP_OPCODE_CMP:
assign4(p, inst, "%s < 0.0F ? %s : %s", src[0], src[1], src[2]);
break;
case FP_OPCODE_COS:
assign4_replicate(p, inst, "COS(%s)", src[0]);
break;
case FP_OPCODE_DP3:
assign4_replicate(p, inst,
"%s*%s + %s*%s + %s*%s",
deref(src[0],_X),
deref(src[1],_X),
deref(src[0],_Y),
deref(src[1],_Y),
deref(src[0],_Z),
deref(src[1],_Z));
break;
case FP_OPCODE_DP4:
assign4_replicate(p, inst,
"%s*%s + %s*%s + %s*%s + %s*%s",
deref(src[0],_X),
deref(src[1],_X),
deref(src[0],_Y),
deref(src[1],_Y),
deref(src[0],_Z),
deref(src[1],_Z));
break;
case FP_OPCODE_DPH:
assign4_replicate(p, inst,
"%s*%s + %s*%s + %s*%s + %s",
deref(src[0],_X),
deref(src[1],_X),
deref(src[0],_Y),
deref(src[1],_Y),
deref(src[1],_Z));
break;
case FP_OPCODE_DST:
/* result[0] = 1 * 1;
* result[1] = a[1] * b[1];
* result[2] = a[2] * 1;
* result[3] = 1 * b[3];
*/
assign_single(0, p, inst, "1.0");
assign_single(1, p, inst, "%s * %s",
deref(src[0], _Y), deref(src[1], _Y));
assign_single(2, p, inst, "%s", deref(src[0], _Z));
assign_single(3, p, inst, "%s", deref(src[1], _W));
break;
case FP_OPCODE_EX2:
assign4_replicate(p, inst, "powf(2.0, %s)", src[0]);
break;
case FP_OPCODE_FLR:
assign4_replicate(p, inst, "floorf(%s)", src[0]);
break;
case FP_OPCODE_FRC:
assign4_replicate(p, inst, "%s - floorf(%s)", src[0], src[0]);
break;
case FP_OPCODE_KIL:
do_tex_kill(p, inst, src[0]);
break;
case FP_OPCODE_LG2:
assign4_replicate(p, inst, "LOG2(%s)", src[0]);
break;
case FP_OPCODE_LIT:
assign_single(0, p, inst, "1.0");
assign_single(1, p, inst, "MIN2(%s, 0)", deref(src[0], _X));
assign_single(2, p, inst, "(%s > 0.0) ? expf(%s * MIN2(%s, 0)) : 0.0",
deref(src[0], _X),
deref(src[0], _Z),
deref(src[0], _Y));
assign_single(3, p, inst, "1.0");
break;
case FP_OPCODE_LRP:
assign4(p, inst,
"%s * %s + (1.0 - %s) * %s",
src[0], src[1], src[0], src[2]);
break;
case FP_OPCODE_MAD:
assign4(p, inst, "%s * %s + %s", src[0], src[1], src[2]);
break;
case FP_OPCODE_MAX:
assign4(p, inst, "MAX2(%s, %s)", src[0], src[1]);
break;
case FP_OPCODE_MIN:
assign4(p, inst, "MIN2(%s, %s)", src[0], src[1]);
break;
case FP_OPCODE_MOV:
assign4(p, inst, "%s", src[0]);
break;
case FP_OPCODE_MUL:
assign4(p, inst, "%s * %s", src[0], src[1]);
break;
case FP_OPCODE_POW:
assign4_replicate(p, inst, "powf(%s, %s)", src[0], src[1]);
break;
case FP_OPCODE_RCP:
assign4_replicate(p, inst, "1.0/%s", src[0]);
break;
case FP_OPCODE_RSQ:
assign4_replicate(p, inst, "_mesa_inv_sqrtf(%s)", src[0]);
break;
case FP_OPCODE_SCS:
if (inst->DstReg.WriteMask[0]) {
assign_single(0, p, inst, "cosf(%s)", deref(src[0], _X));
}
if (inst->DstReg.WriteMask[1]) {
assign_single(1, p, inst, "sinf(%s)", deref(src[0], _X));
}
break;
case FP_OPCODE_SGE:
assign4(p, inst, "%s >= %s ? 1.0 : 0.0", src[0], src[1]);
break;
case FP_OPCODE_SIN:
assign4_replicate(p, inst, "sinf(%s)", src[0]);
break;
case FP_OPCODE_SLT:
assign4(p, inst, "%s < %s ? 1.0 : 0.0", src[0], src[1]);
break;
case FP_OPCODE_SUB:
assign4(p, inst, "%s - %s", src[0], src[1]);
break;
case FP_OPCODE_SWZ: /* same implementation as MOV: */
assign4(p, inst, "%s", src[0]);
break;
case FP_OPCODE_TEX:
do_tex(p, inst, "TEX", inst->TexSrcUnit, src[0]);
break;
case FP_OPCODE_TXB:
do_tex(p, inst, "TXB", inst->TexSrcUnit, src[0]);
break;
case FP_OPCODE_TXP:
do_tex(p, inst, "TXP", inst->TexSrcUnit, src[0]);
break;
case FP_OPCODE_XPD:
/* Cross product:
* result.x = src[0].y * src[1].z - src[0].z * src[1].y;
* result.y = src[0].z * src[1].x - src[0].x * src[1].z;
* result.z = src[0].x * src[1].y - src[0].y * src[1].x;
* result.w = undef;
*/
assign4(p, inst,
"%s * %s - %s * %s",
swizzle(src[0], _Y, _Z, _X, _ONE),
swizzle(src[1], _Z, _X, _Y, _ONE),
swizzle(src[0], _Z, _X, _Y, _ONE),
swizzle(src[1], _Y, _Z, _X, _ONE));
break;
default:
emit(p, "BOGUS OPCODE\n");
return;
}
}
}
void _swrast_translate_program( GLcontext *ctx )
{
struct fragment_program *p = ctx->FragmentProgram._Current;
if (p) {
p->c_strlen = 0;
print_header( p );
translate_program( p );
print_footer( p );
}
}
#endif /*USE_TCC*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -