added ARL, EXP, LOG, relative indexing
This commit is contained in:
@@ -53,6 +53,27 @@
|
||||
#define DEBUG_PROG 0
|
||||
|
||||
|
||||
/**
|
||||
* Set x to positive or negative infinity.
|
||||
*/
|
||||
#if defined(USE_IEEE) || defined(_WIN32)
|
||||
#define SET_POS_INFINITY(x) ( *((GLuint *) (void *)&x) = 0x7F800000 )
|
||||
#define SET_NEG_INFINITY(x) ( *((GLuint *) (void *)&x) = 0xFF800000 )
|
||||
#elif defined(VMS)
|
||||
#define SET_POS_INFINITY(x) x = __MAXFLOAT
|
||||
#define SET_NEG_INFINITY(x) x = -__MAXFLOAT
|
||||
#else
|
||||
#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL
|
||||
#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL
|
||||
#endif
|
||||
|
||||
#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
|
||||
|
||||
|
||||
static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
|
||||
|
||||
|
||||
|
||||
#if FEATURE_MESA_program_debug
|
||||
static struct gl_program_machine *CurrentMachine = NULL;
|
||||
|
||||
@@ -102,6 +123,24 @@ get_register_pointer(GLcontext * ctx,
|
||||
const struct gl_program_machine *machine)
|
||||
{
|
||||
/* XXX relative addressing... */
|
||||
|
||||
if (source->RelAddr) {
|
||||
const GLint reg = source->Index + machine->AddressReg[0][0];
|
||||
ASSERT( (source->File == PROGRAM_ENV_PARAM) ||
|
||||
(source->File == PROGRAM_STATE_VAR) );
|
||||
if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
|
||||
return ZeroVec;
|
||||
else if (source->File == PROGRAM_ENV_PARAM)
|
||||
return ctx->VertexProgram.Parameters[reg];
|
||||
else {
|
||||
/*
|
||||
ASSERT(source->File == PROGRAM_LOCAL_PARAM);
|
||||
*/
|
||||
return machine->CurProgram->Parameters->ParameterValues[reg];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (source->File) {
|
||||
case PROGRAM_TEMPORARY:
|
||||
ASSERT(source->Index < MAX_PROGRAM_TEMPS);
|
||||
@@ -665,6 +704,13 @@ _mesa_execute_program(GLcontext * ctx,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPCODE_ARL:
|
||||
{
|
||||
GLfloat t[4];
|
||||
fetch_vector4(ctx, &inst->SrcReg[0], machine, t);
|
||||
machine->AddressReg[0][0] = (GLint) FLOORF(t[0]);
|
||||
}
|
||||
break;
|
||||
case OPCODE_BGNLOOP:
|
||||
/* no-op */
|
||||
break;
|
||||
@@ -746,8 +792,7 @@ _mesa_execute_program(GLcontext * ctx,
|
||||
}
|
||||
store_vector4(inst, machine, result);
|
||||
#else
|
||||
static const GLfloat result[4] = { 0, 0, 0, 0 };
|
||||
store_vector4(inst, machine, result);
|
||||
store_vector4(inst, machine, ZeroVec);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -771,8 +816,7 @@ _mesa_execute_program(GLcontext * ctx,
|
||||
}
|
||||
store_vector4(inst, machine, result);
|
||||
#else
|
||||
static const GLfloat result[4] = { 0, 0, 0, 0 };
|
||||
store_vector4(inst, machine, result);
|
||||
store_vector4(inst, machine, ZeroVec);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
@@ -825,6 +869,36 @@ _mesa_execute_program(GLcontext * ctx,
|
||||
store_vector4(inst, machine, result);
|
||||
}
|
||||
break;
|
||||
case OPCODE_EXP:
|
||||
/* XXX currently broken! */
|
||||
{
|
||||
GLfloat t[4], q[4], floor_t0;
|
||||
fetch_vector1(ctx, &inst->SrcReg[0], machine, t);
|
||||
floor_t0 = FLOORF(t[0]);
|
||||
if (floor_t0 > FLT_MAX_EXP) {
|
||||
SET_POS_INFINITY(q[0]);
|
||||
SET_POS_INFINITY(q[2]);
|
||||
}
|
||||
else if (floor_t0 < FLT_MIN_EXP) {
|
||||
q[0] = 0.0F;
|
||||
q[2] = 0.0F;
|
||||
}
|
||||
else {
|
||||
#ifdef USE_IEEE
|
||||
GLint ii = (GLint) floor_t0;
|
||||
ii = (ii < 23) + 0x3f800000;
|
||||
SET_FLOAT_BITS(q[0], ii);
|
||||
q[0] = *((GLfloat *) (void *)&ii);
|
||||
#else
|
||||
q[0] = (GLfloat) pow(2.0, floor_t0);
|
||||
#endif
|
||||
q[2] = (GLfloat) (q[0] * LOG2(q[1]));
|
||||
}
|
||||
q[1] = t[0] - floor_t0;
|
||||
q[3] = 1.0F;
|
||||
store_vector4( inst, machine, q );
|
||||
}
|
||||
break;
|
||||
case OPCODE_EX2: /* Exponential base 2 */
|
||||
{
|
||||
GLfloat a[4], result[4];
|
||||
@@ -937,6 +1011,43 @@ _mesa_execute_program(GLcontext * ctx,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPCODE_LOG:
|
||||
{
|
||||
GLfloat t[4], q[4], abs_t0;
|
||||
fetch_vector1(ctx, &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];
|
||||
|
Reference in New Issue
Block a user