jingwood / d2dlib

A .NET library for hardware-accelerated, high performance, immediate mode rendering via Direct2D.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage of System.Numerics.VectorX

nikeee opened this issue · comments

I love this library.

One thing I noticed:
I often need to convert the structs D2DPoint to Vector2.
One reason being that VectorX structs have operator overloading. The other reason is that they support JIT intrinsics and take advantage of SIMD extensions of the CPU, so math operations are much faster with them.

Is it possible to use them directly with this library? Vector2 is basically this struct:

struct Vector2 {
    float x;
    float y;
}

Notice: It does not have the SequentialLayout attribute, so it might be padded during runtime. However, the .NET docs state:

C#, Visual Basic, and C++ compilers apply the Sequential layout value to structures by default. For classes, you must apply the LayoutKind.Sequential value explicitly.

To get an idea, this is the Vector2 implementation:
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs

If these structs are ABI compatible, one could just pass them instead of D2DPoint etc. Ist would eliminate conversions as well as increase performance due to hardware acceleration.

Edit:
Matrix3x2 also seems that it has the same binary layout as the one in System.Numerics:
https://github.com/dotnet/runtime/blob/01b7e73cd378145264a7cb7a09365b41ed42b240/src/libraries/System.Private.CoreLib/src/System/Numerics/Matrix3x2.cs#L82

Any chances on something in that direction?

Hi @nikeee!

Thanks for the suggestions! I think it's a nice idea!

The D2DPoint was designed to keep the same layout compared to the structure defined on C++ side. So it's the first goal is to keep API calling is safe and fast, then the calculation performance. But maybe the Vector2 works well also, I will have a check.

You may consider performing calculations using System.Numerics.* then pass the result to D2DLib using D2DPoint etc. I think there is also a good idea to make more implicit conversion available between System.Numerics.* and D2DPoint classes.

@drewnoakes Any suggestions will be helpful!

Using the System.Numerics types seems like a good idea.

Vector2 appears to be an intrinsic: https://github.com/dotnet/runtime/blob/9cb0ab915e971f6408aae662a8dec7fcf365930e/src/libraries/System.Private.CoreLib/src/System/Numerics/Vector2.cs#L18-L25

I doubt the layout would change though. It looks identical to D2DPoint. Try it and see I guess.

Implicit conversions can be convenient but can also be suprising. They can also result in redundant copying of values, compared to reusing Vector2.

I tried this one out (with Vector2 and Matrix3x2) and it works pretty well:
https://github.com/nikeee/nud2dlib

Is it possible to tackle this or find any solution?

I see that the library was ported to .NET 6, which was one of my core goals for nud2dlib (though at that time, it was .NET 5).

They both do basically the same, the only difference for now being that nud2dlib uses Vector2/Vector3 and Matrix3x2 in in some places where D2DPoint or D2DSize is used.

However, the projects start to diverge in some ways. For example, d2dlib recently enhanced the text rendering capabilities. While I'm fine with backporting stuff, I'd also like to give back some of my efforts (like #30, #65 and #82).

One non-breaking solution would be to add a some overloads to the functions recieving D2DPoints. This wouldn't require automatic/implicit conversions from Vector2 to D2DPoint. The C wrapper library could remain the same, since both structs are binary compatible.

I that something you'd see in the scope of this project?

@jingwood would it be feasible to remove D2DPoint altogether, and use Vector2 instead?

@nikeee @drewnoakes OK, use System.Numerics.* from the next version!

@nikeee @drewnoakes If possible please have a review for #97

Very cool! I'll do a review tomorrow! :)

Fixed in #97.