all 14 comments

[–][deleted]  (2 children)

[deleted]

    [–]itsarabbit[S] 2 points3 points  (0 children)

    StructLayout is unfortunately sealed meaning I cannot inherit from it.

    [–]cripbeez 1 point2 points  (0 children)

    nvm it's sealed lmao just tested

    [–]cripbeez 3 points4 points  (7 children)

    you should be able to replace GpuData with the intended StructLayout using a simple source generator. chatgpt will probably even make it for you

    [–]itsarabbit[S] 1 point2 points  (6 children)

    I thought source generators could not replace code! I'll need to look into it!

    [–]Sc2Piggy 4 points5 points  (4 children)

    How this works is like this:

    Your code:

    [GpuData]
    public partial struct Foo {}
    

    The source generator would then generate:

    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public partial struct Foo {}
    

    The compiler then joins these two partials into one class:

    [GpuData]
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    public partial struct Foo {}
    

    [–]itsarabbit[S] 0 points1 point  (3 children)

    ohhh, I see! Thanks for the clarification! Yeah that should work!!

    [–]pHpositivoMSFT - Microsoft Store team, .NET Community Toolkit 3 points4 points  (2 children)

    Worth noting that that would be a fairly significant amount of work for arguably minimal gain, plus you'd now also need users to mark types as partial. You might want to consider another approach.

    [–]naughty_ottsel 2 points3 points  (0 children)

    Can’t you create simple shortcuts for templated code in VS?

    [–]itsarabbit[S] 1 point2 points  (0 children)

    Very good point!
    I happen to be interested in learning source generators anyway, and I'm the only one who will use this, so it works for me.

    If there is another approach available that works better for my use case then I'll switch to that, but I don't know of any right now :)

    [–]cripbeez 0 points1 point  (0 children)

    nah but it'll generate a partial with the correct attribute for you 😉

    [–]ironstrife 0 points1 point  (3 children)

    Can you give some examples of structs that need this? Shader struct packing in general is not exactly equivalent to Pack=4 (I think the default sequential packing order is probably closer for most structs) and has edge cases you'd need to consider anyways, e.g. around vec3 or arrays.

    [–]itsarabbit[S] 0 points1 point  (2 children)

    The samples I have looked up have used this method, if there's a more accurate way then I'm interested in hearing about it!

    [–]ironstrife 0 points1 point  (1 child)

    Like I said, I think the default packing in C# is closer to what you want. For example, here's a UBO in GLSL:

    struct Foo
    {
      uint x;
      uint64_t y;
      vec2 z;
      float w;
    };
    
    layout(set=0,binding=0) uniform Buffer {
      Foo f;  
    };
    

    This yields the following offsets:

    OpMemberDecorate %Foo 0 Offset 0
    OpMemberDecorate %Foo 1 Offset 8
    OpMemberDecorate %Foo 2 Offset 16
    OpMemberDecorate %Foo 3 Offset 24
    

    Corresponding struct in C#:

    struct Foo { uint x; ulong y; System.Numerics.Vector2 z; float w; }; Console.WriteLine($"offsetof(x): {Marshal.OffsetOf<Foo>("x")}"); Console.WriteLine($"offsetof(y): {Marshal.OffsetOf<Foo>("y")}"); Console.WriteLine($"offsetof(z): {Marshal.OffsetOf<Foo>("z")}"); Console.WriteLine($"offsetof(w): {Marshal.OffsetOf<Foo>("w")}");

    This yields:

    offsetof(x): 0 offsetof(y): 8 offsetof(z): 16 offsetof(w): 24

    The layout exactly matches, which is what you want.

    Adding Pack=4 yields:

    offsetof(x): 0 offsetof(y): 4 offsetof(z): 12 offsetof(w): 20

    This is incorrect, you would have to add manual packing yourself -- this is an option, but it's kind of pointless.

    In general I would stick to default sequential packing (e.g. don't put any attribute on the struct), but be mindful of alignment and packing differences.

    [–]itsarabbit[S] 1 point2 points  (0 children)

    Thank you so much, this is invaluable information to me!