mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 02:11:19 +00:00
Fix the vector/quaternion scaling instructions.
It was pointed out by Blub\w (gmqcc) that OP_MUL_FV and friends were buggy when the operands overlapped (eg, x = x.x * x) as the result would become 'x.x*x.x x.y*x.x*x.x x.z*x.x*x.x' (note the x.x squared for y and z). On testing, sure enough the bug was present (and is a nice demonstration that QF's VM does NOT have strict-aliasing bugs). As a very nice benefit: the code produced by the fixes is actually faster than the broken version :). The ruamoko code used for testing: void (string fmt, ...) printf = #0; vector foo (vector x) { x = x * x.x; return x; } vector bar (vector x) { x = x.x * x; return x; } int main () { vector x = '2 3 4'; vector y = foo (x); vector z = bar (x); printf ("x=%v y=%v z=%v 2*x=%v\n", x, y, z, 2*x); return 0; }
This commit is contained in:
parent
5b47c15611
commit
3c67e8f020
1 changed files with 24 additions and 4 deletions
|
@ -430,10 +430,20 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
OPC.float_var = DotProduct (OPA.vector_var, OPB.vector_var);
|
||||
break;
|
||||
case OP_MUL_FV:
|
||||
VectorScale (OPB.vector_var, OPA.float_var, OPC.vector_var);
|
||||
{
|
||||
// avoid issues with the likes of x = x.x * x;
|
||||
// makes for faster code, too
|
||||
float scale = OPA.float_var;
|
||||
VectorScale (OPB.vector_var, scale, OPC.vector_var);
|
||||
}
|
||||
break;
|
||||
case OP_MUL_VF:
|
||||
VectorScale (OPA.vector_var, OPB.float_var, OPC.vector_var);
|
||||
{
|
||||
// avoid issues with the likes of x = x * x.x;
|
||||
// makes for faster code, too
|
||||
float scale = OPB.float_var;
|
||||
VectorScale (OPA.vector_var, scale, OPC.vector_var);
|
||||
}
|
||||
break;
|
||||
case OP_MUL_Q:
|
||||
QuatMult (OPA.quat_var, OPB.quat_var, OPC.quat_var);
|
||||
|
@ -442,10 +452,20 @@ PR_ExecuteProgram (progs_t * pr, func_t fnum)
|
|||
QuatMultVec (OPA.quat_var, OPB.vector_var, OPC.vector_var);
|
||||
break;
|
||||
case OP_MUL_FQ:
|
||||
QuatScale (OPB.quat_var, OPA.float_var, OPC.quat_var);
|
||||
{
|
||||
// avoid issues with the likes of x = x.s * x;
|
||||
// makes for faster code, too
|
||||
float scale = OPA.float_var;
|
||||
QuatScale (OPB.quat_var, scale, OPC.quat_var);
|
||||
}
|
||||
break;
|
||||
case OP_MUL_QF:
|
||||
QuatScale (OPA.quat_var, OPB.float_var, OPC.quat_var);
|
||||
{
|
||||
// avoid issues with the likes of x = x * x.s;
|
||||
// makes for faster code, too
|
||||
float scale = OPB.float_var;
|
||||
QuatScale (OPA.quat_var, scale, OPC.quat_var);
|
||||
}
|
||||
break;
|
||||
case OP_CONJ_Q:
|
||||
QuatConj (OPA.quat_var, OPC.quat_var);
|
||||
|
|
Loading…
Reference in a new issue