📄 prog_execute.c
字号:
/* do if/else */ if (cond) { /* do if-clause (just continue execution) */ } else { /* go to the instruction after ELSE or ENDIF */ assert(inst->BranchTarget >= 0); pc = inst->BranchTarget - 1; } } break; case OPCODE_ELSE: /* goto ENDIF */ assert(inst->BranchTarget >= 0); pc = inst->BranchTarget - 1; break; case OPCODE_ENDIF: /* nothing */ break; case OPCODE_INT: /* float to int */ { GLfloat a[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); result[0] = (GLfloat) (GLint) a[0]; result[1] = (GLfloat) (GLint) a[1]; result[2] = (GLfloat) (GLint) a[2]; result[3] = (GLfloat) (GLint) a[3]; store_vector4(inst, machine, result); } break; case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ if (eval_condition(machine, inst)) { return GL_FALSE; } break; case OPCODE_KIL: /* ARB_f_p only */ { GLfloat a[4]; fetch_vector4(&inst->SrcReg[0], machine, a); if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { return GL_FALSE; } } break; case OPCODE_LG2: /* log base 2 */ { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); store_vector4(inst, machine, result); } break; case OPCODE_LIT: { const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ GLfloat a[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = MAX2(a[0], 0.0F); a[1] = MAX2(a[1], 0.0F); /* XXX ARB version clamps a[3], NV version doesn't */ a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); result[0] = 1.0F; result[1] = a[0]; /* XXX we could probably just use pow() here */ if (a[0] > 0.0F) { if (a[1] == 0.0 && a[3] == 0.0) result[2] = 1.0; else result[2] = EXPF(a[3] * LOGF(a[1])); } else { result[2] = 0.0; } result[3] = 1.0F; store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", result[0], result[1], result[2], result[3], a[0], a[1], a[2], a[3]); } } break; case OPCODE_LOG: { GLfloat t[4], q[4], abs_t0; fetch_vector1(&inst->SrcReg[0], machine, t); abs_t0 = FABSF(t[0]); if (abs_t0 != 0.0F) { /* Since we really can't handle infinite values on VMS * like other OSes we'll use __MAXFLOAT to represent * infinity. This may need some tweaking. */#ifdef VMS if (abs_t0 == __MAXFLOAT)#else if (IS_INF_OR_NAN(abs_t0))#endif { SET_POS_INFINITY(q[0]); q[1] = 1.0F; SET_POS_INFINITY(q[2]); } else { int exponent; GLfloat mantissa = FREXPF(t[0], &exponent); q[0] = (GLfloat) (exponent - 1); q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ q[2] = (GLfloat) (q[0] + LOG2(q[1])); } } else { SET_NEG_INFINITY(q[0]); q[1] = 1.0F; SET_NEG_INFINITY(q[2]); } q[3] = 1.0; store_vector4(inst, machine, q); } break; case OPCODE_LRP: { GLfloat a[4], b[4], c[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); fetch_vector4(&inst->SrcReg[1], machine, b); fetch_vector4(&inst->SrcReg[2], machine, c); result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("LRP (%g %g %g %g) = (%g %g %g %g), " "(%g %g %g %g), (%g %g %g %g)\n", result[0], result[1], result[2], result[3], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); } } break; case OPCODE_MAD: { GLfloat a[4], b[4], c[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); fetch_vector4(&inst->SrcReg[1], machine, b); fetch_vector4(&inst->SrcReg[2], machine, c); result[0] = a[0] * b[0] + c[0]; result[1] = a[1] * b[1] + c[1]; result[2] = a[2] * b[2] + c[2]; result[3] = a[3] * b[3] + c[3]; store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("MAD (%g %g %g %g) = (%g %g %g %g) * " "(%g %g %g %g) + (%g %g %g %g)\n", result[0], result[1], result[2], result[3], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); } } break; case OPCODE_MAX: { GLfloat a[4], b[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); fetch_vector4(&inst->SrcReg[1], machine, b); result[0] = MAX2(a[0], b[0]); result[1] = MAX2(a[1], b[1]); result[2] = MAX2(a[2], b[2]); result[3] = MAX2(a[3], b[3]); store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", result[0], result[1], result[2], result[3], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); } } break; case OPCODE_MIN: { GLfloat a[4], b[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); fetch_vector4(&inst->SrcReg[1], machine, b); result[0] = MIN2(a[0], b[0]); result[1] = MIN2(a[1], b[1]); result[2] = MIN2(a[2], b[2]); result[3] = MIN2(a[3], b[3]); store_vector4(inst, machine, result); } break; case OPCODE_MOV: { GLfloat result[4]; fetch_vector4(&inst->SrcReg[0], machine, result); store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("MOV (%g %g %g %g)\n", result[0], result[1], result[2], result[3]); } } break; case OPCODE_MUL: { GLfloat a[4], b[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); fetch_vector4(&inst->SrcReg[1], machine, b); result[0] = a[0] * b[0]; result[1] = a[1] * b[1]; result[2] = a[2] * b[2]; result[3] = a[3] * b[3]; store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", result[0], result[1], result[2], result[3], a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); } } break; case OPCODE_NOISE1: { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = _slang_library_noise1(a[0]); store_vector4(inst, machine, result); } break; case OPCODE_NOISE2: { GLfloat a[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = _slang_library_noise2(a[0], a[1]); store_vector4(inst, machine, result); } break; case OPCODE_NOISE3: { GLfloat a[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = _slang_library_noise3(a[0], a[1], a[2]); store_vector4(inst, machine, result); } break; case OPCODE_NOISE4: { GLfloat a[4], result[4]; fetch_vector4(&inst->SrcReg[0], machine, a); result[0] = result[1] = result[2] = result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]); store_vector4(inst, machine, result); } break; case OPCODE_NOP: break; case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ { GLfloat a[4], result[4]; GLhalfNV hx, hy; GLuint *rawResult = (GLuint *) result; GLuint twoHalves; fetch_vector4(&inst->SrcReg[0], machine, a); hx = _mesa_float_to_half(a[0]); hy = _mesa_float_to_half(a[1]); twoHalves = hx | (hy << 16); rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] = twoHalves; store_vector4(inst, machine, result); } break; case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ { GLfloat a[4], result[4]; GLuint usx, usy, *rawResult = (GLuint *) result; fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = CLAMP(a[0], 0.0F, 1.0F); a[1] = CLAMP(a[1], 0.0F, 1.0F); usx = IROUND(a[0] * 65535.0F); usy = IROUND(a[1] * 65535.0F); rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] = usx | (usy << 16); store_vector4(inst, machine, result); } break; case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ { GLfloat a[4], result[4]; GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); ubx = IROUND(127.0F * a[0] + 128.0F); uby = IROUND(127.0F * a[1] + 128.0F); ubz = IROUND(127.0F * a[2] + 128.0F); ubw = IROUND(127.0F * a[3] + 128.0F); rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); store_vector4(inst, machine, result); } break; case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ { GLfloat a[4], result[4]; GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = CLAMP(a[0], 0.0F, 1.0F); a[1] = CLAMP(a[1], 0.0F, 1.0F); a[2] = CLAMP(a[2], 0.0F, 1.0F); a[3] = CLAMP(a[3], 0.0F, 1.0F); ubx = IROUND(255.0F * a[0]); uby = IROUND(255.0F * a[1]); ubz = IROUND(255.0F * a[2]); ubw = IROUND(255.0F * a[3]); rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); store_vector4(inst, machine, result); } break; case OPCODE_POW: { GLfloat a[4], b[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); fetch_vector1(&inst->SrcReg[1], machine, b); result[0] = result[1] = result[2] = result[3] = (GLfloat) _mesa_pow(a[0], b[0]); store_vector4(inst, machine, result); } break; case OPCODE_RCP: { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); if (DEBUG_PROG) { if (a[0] == 0) printf("RCP(0)\n"); else if (IS_INF_OR_NAN(a[0])) printf("RCP(inf)\n"); } result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; store_vector4(inst, machine, result); } break; case OPCODE_RET: /* return from subroutine (conditional) */ if (eval_condition(machine, inst)) { if (machine->StackDepth == 0) { return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } /* subtract one because of pc++ in the for loop */ pc = machine->CallStack[--machine->StackDepth] - 1; } break; case OPCODE_RFL: /* reflection vector */ { GLfloat axis[4], dir[4], result[4], tmpX, tmpW; fetch_vector4(&inst->SrcReg[0], machine, axis); fetch_vector4(&inst->SrcReg[1], machine, dir); tmpW = DOT3(axis, axis); tmpX = (2.0F * DOT3(axis, dir)) / tmpW; result[0] = tmpX * axis[0] - dir[0]; result[1] = tmpX * axis[1] - dir[1]; result[2] = tmpX * axis[2] - dir[2]; /* result[3] is never written! XXX enforce in parser! */ store_vector4(inst, machine, result); } break; case OPCODE_RSQ: /* 1 / sqrt() */ { GLfloat a[4], result[4]; fetch_vector1(&inst->SrcReg[0], machine, a); a[0] = FABSF(a[0]); result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); store_vector4(inst, machine, result); if (DEBUG_PROG) { printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); } } break; case OPCODE_SCS: /* sine and cos */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -