scripts : optimize swizzling across AST node-chains
- merge des swizzles multiples:
v = truc.xywz.xzwy.zzwx
v = truc.xwzy.wwyx
v = truc.yywx
- merge des swizzles multiples a travers les operations arithmetiques de base et les expressions le permettant:
v = (frac(3 * sin(truc + 2).xywz - 10.0).xzwy / cos(float(y) - 0.1)).zzwx
v = (frac(3 * sin(truc + 2) - 10.0).xwzy / cos(float(y) - 0.1)).wwyx
v = (frac(3 * sin(truc + 2) - 10.0) / cos(float(y) - 0.1)).yywx
- s'arreter lorsque l'arbre d'expression contient des expression non-constantes necessitant une insertion de swizzle pour continuer. ca ne vaudrait pas le coup. sauf eventuellement dans quelques rares cas ?
- ATTENTION A LA PROPAGATION DES SWIZZLES DANS LES CONSTANTES !!
ex:
v = (frac(3 * sin(truc + 2).xywz - 10.0).xzwy / cos(float4(0.125, 0.25, 0.5, 1.0))).zzwx
v = (frac(3 * sin(truc + 2) - 10.0).xwzy / cos(float4(0.125, 0.25, 0.5, 1.0))).wwyx
v = (frac(3 * sin(truc + 2) - 10.0) / cos(float4(0.125, 0.25, 0.5, 1.0))).yywx <-- ERREUR !!!
XYZW -> XYWZ -> XWZY / {0.125, 0.25, 0.5, 1.0}
X=0.125
Y=0.25
Z=0.5
W=1.0
(XYZW / {0.125, 1.0, 0.5, 0.25}).xwzy
(XYZW / {0.125, 0.25, 0.5, 1.0}.xwzy).xwzy
- NOTE: we can't do all this when there is a swizzle that does value duplication, and we're throwing the duplicated value inside different ops, ex:
stuff.xxyz * float4(1,2,3,4)
here, we can't rearrange this with an expression like:
(stuff * float4(a,b,c,d)).xxyz
for obvious reasons...
recap:
v = (frac(3 * sin(truc + 2).xywz - 10.0).xzwy / cos(float4(0.125, 0.25, 0.5, 1.0))).zzwx
v = (frac(3 * sin(truc + 2) - 10.0).xwzy / cos(float4(0.125, 0.25, 0.5, 1.0))).wwyx
v = (frac(3 * sin(truc + 2) - 10.0) / cos(float4(0.125, 0.25, 0.5, 1.0).xwzy)).yywx
basically, when an operand of an op that treats all vector components the same way (like basic operators, sin, cos, frac, dot, length, etc...), is a non-scalar, we need to swizzle it with the swizzle mask we're propagating to continue propagation down the branches.

HURRRR !