Jump to content
  • Advertisement
Sign in to follow this  
CyberRascal

C++ struct as value in array, what about cross platform padding?

This topic is 2434 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Certain functions, for example glBufferData takes a pointer to an array, for example with x, y, z, tex and so on. It's convenient to store these values in a statically typed struct, and I've seen several developers do this. But the problem is that a compiler can insert padding into a struct on an implementation basis. You could use pragma pack, but its compiler specific. How do you solve this in an efficient way?

I'm on my phone, so I apologize for any weirdness.

Share this post


Link to post
Share on other sites
Advertisement
As I see it your two best options are likely:
1. Simply don't worry about padding until it actually has become a bottleneck. Use sizeof and let it be. Might be a waste of time to worry about it.
2. If you know it's a problem use pragma pack or whatever your current compiler requires and don't worry about compiling on some different compiler until you actually need it. Add ifdef for specific compilers when you do.

Share this post


Link to post
Share on other sites
Solve what exactly?
That your struct layout might not match your idea GL vertex layout.
e.g. Given a vertex layout that has float x/y/z position, 8 bit tex-coords, and float RGB colour, we could write this structstruct Vertex {
float x, y, z;
unsigned char u, v;
// most compilers will insert padding here, e.g. "char _pad_[2];"
float r, g, b;
};
The problem is that because of the padding, our struct doesn't match the original description, so you can't give it to GL.

To solve this, either use pragma pack (it is fairly cross-platform, I use it often at work), or simply don't use structs like this ;)

Share this post


Link to post
Share on other sites
The most applicable example for this that I considered was also vertex packing for OpenGL.
In my case I store everything in an LSUINT8 * array (LSUINT8 = unsigned char).
I can then enforce my own alignment conditions and be sure they are always the same alignment on every platform.

OpenGL is going to accept any stride you give it, so if you are aware that certain platforms like certain alignments on your data types, and would otherwise adjust your structures accordingly, you can handle this type of alignment manually with little effort, but guaranteed results.
If you don’t handle these, you are still guarantee that your code will work anyway, even if it is a little slower.
If it were to crash due to floats not being 4-byte aligned (hello armv7 without floating-point library calls), at least the crash is easily traceable to its actual source. Without crashing, you would be left with jumbled OpenGL ES 2 graphics and cranking up your puzzler.


L. Spiro

Share this post


Link to post
Share on other sites

[quote name='Rene Z' timestamp='1332245371' post='4923588']Solve what exactly?
That your struct layout might not match your idea GL vertex layout.
e.g. Given a vertex layout that has float x/y/z position, 8 bit tex-coords, and float RGB colour, we could write this structstruct Vertex {
float x, y, z;
unsigned char u, v;
// most compilers will insert padding here, e.g. "char _pad_[2];"
float r, g, b;
};
The problem is that because of the padding, our struct doesn't match the original description, so you can't give it to GL.

To solve this, either use pragma pack (it is fairly cross-platform, I use it often at work), or simply don't use structs like this ;)
[/quote]
For the record, unless padding is inserted in the middle of the doublets/triplets, the padding between the texture coordinate and the color is no problem for OpenGL. That structure is, in practice, perfectly fine.

Share this post


Link to post
Share on other sites

For the record, unless padding is inserted in the middle of the doublets/triplets, the padding between the texture coordinate and the color is no problem for OpenGL. That structure is, in practice, perfectly fine.


How do you mean 'is no problem' for OpenGL? It doesn't know anything about your struct. Do you mean that you would use stride = sizeof(struct) and then offset according to what field you are interested in? Or something else? offsetof seems to be somewhat deprecated / frowned upon, and even so it might not be possible if the padding is in the wrong place?


OpenGL is going to accept any stride you give it, so if you are aware that certain platforms like certain alignments on your data types, and would otherwise adjust your structures accordingly, you can handle this type of alignment manually with little effort, but guaranteed results.


How do you mean, handle with little effort? How would you handle it?

Cheers :)

Share this post


Link to post
Share on other sites

That your struct layout might not match your idea GL vertex layout.
e.g. Given a vertex layout that has float x/y/z position, 8 bit tex-coords, and float RGB colour, we could write this structstruct Vertex {
float x, y, z;
unsigned char u, v;
// most compilers will insert padding here, e.g. "char _pad_[2];"
float r, g, b;
};
The problem is that because of the padding, our struct doesn't match the original description, so you can't give it to GL.

To solve this, either use pragma pack (it is fairly cross-platform, I use it often at work), or simply don't use structs like this ;)


Couldn't you solve this by adjusting the stride when calling glVertexPointer, glTexCoord, etc. using offsetof?

Share this post


Link to post
Share on other sites

[quote name='Brother Bob' timestamp='1332254622' post='4923630']
For the record, unless padding is inserted in the middle of the doublets/triplets, the padding between the texture coordinate and the color is no problem for OpenGL. That structure is, in practice, perfectly fine.


How do you mean 'is no problem' for OpenGL? It doesn't know anything about your struct. Do you mean that you would use stride = sizeof(struct) and then offset according to what field you are interested in? Or something else? offsetof seems to be somewhat deprecated / frowned upon, and even so it might not be possible if the padding is in the wrong place?
[/quote]
OpenGL doesn't know about your structure, but you know about it. No matter how much padding is inserted, the stride in an array of structures is always sizeof() the struct, and offsetof() can be used to get the offset. The stride and the offsets are all you need to properly use the structure in a vertex array.

Share this post


Link to post
Share on other sites
struct Vertex {
float x, y, PADDING, z;
unsigned char u, v;
float r, g, b;
};


The above is unlikely, but theoretically possible. It's as possible as the compiler inserting a pad between the semantic data (i.e you can fix it with offsetof). If this happens it won't work whatever you do using offsetof?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!