Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hardware-accelerated Matrix4x4f results are different from software results #145

Open
EmVeeKee opened this issue Sep 13, 2019 · 3 comments

Comments

@EmVeeKee
Copy link

Hello Luca,

First: really like the code!

When switching from x86 to x64 mode I noticed odd behavior in my CPU matrix operations. It turns out that on my laptop in x64 mode the hardware acceleration kicks in when multiplying Matrix4x4f (see opengl.net.math, matrix.cs, public static Matrix4x4f operator*(Matrix4x4f m, Matrix4x4f n) ).

"
#if HAVE_NUMERICS
if (Vector.IsHardwareAccelerated) {
unsafe {
Unsafe.Write(&r, Unsafe.Read(&m) * Unsafe.Read(&n));
}
} else {
#endif
"
However, the result of this multiplication is different from the code that is used in absence of hardware acceleration. And at least for me the 'software' version works.

Depending on using/not using the Mat4x4 hardware accelearated multiplication, I get the results below for a 'Scaled(0.5f, 0.5f, 1.0f) * Translated(3f, 3f, 3f)'. In the accelerated case I get the full translation (no scaling by 0.5f), in the software case I get the (for me) correct shift of 1.5f.

res = {||0.5, 0, 0, 0||0, 0.5, 0, 0||0, 0, 1, 0||3, 3, 3, 1||}
res = {||0.5, 0, 0, 0||0, 0.5, 0, 0||0, 0, 1, 0||1.5, 1.5, 3, 1||}

        Matrix4x4f scale05 = Matrix4x4f.Identity;
        scale05.Scale(0.5f, 0.5f, 1.0f);            

        Matrix4x4f trans333 = Matrix4x4f.Translated(3f, 3f, 3f);
        Matrix4x4f res = scale05 * trans333;

        var x = Unsafe.Read<Mat4x4>(&scale05);
        var y = Unsafe.Read<Mat4x4>(&trans333);            
        var z = y * x;

Best regards,

Maarten

@EmVeeKee
Copy link
Author

Looked into it a bit more. With a and b are both Matrix4x4f, then the software multiplication a*b is identical to the hardware accelerated multiplication transpose(transpose(a) * transpose(b)). Hence it seems that e.g. Unsafe.Read(&a) will effectively transform Matrix4x4f a into Mat4x4 transpose(a).

@luca-piccioni
Copy link
Owner

Thank you!

Evidently it means that arguments are intended as row-major matrices. Ouch.

Indeed we need to transpose 3x times? Maybe it's better to remove Numerics from Matrix*.

@EmVeeKee
Copy link
Author

EmVeeKee commented Sep 14, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants