Well yesterday i got a really weird issue where my game crashed reproduceable at the exact same spot: Trying to set the color for the ~407 th line added to my render buffer.
This looks like this is very straightforward (Memory for this is already pre-allocated, so there was no concerns about that):
struct RenderState {
u8 *commandBufferBase;
mem_size commandBufferSize;
mem_size commandBufferUsed;
};
struct RenderCommand {
RenderCommandType type;
Vec4f color;
Transform transform;
union {
RenderCommandClear clear;
RenderCommandLines lines;
RenderCommandPolygon polygon;
RenderCommandCircle circle;
RenderCommandSprite sprite;
};
};
internal RenderCommand *RenderPush(RenderState *renderState, RenderCommandType type, Transform *transform, const Vec4f &color) {
mem_size size = sizeof(RenderCommand);
Assert(renderState->commandBufferUsed + size <= renderState->commandBufferSize);
void *renderCommandBase = (u8 *)renderState->commandBufferBase + renderState->commandBufferUsed;
renderState->commandBufferUsed += size;
RenderCommand *result = (RenderCommand *)renderCommandBase;
ZeroStruct(result);
result->type = type;
result->color = color; // <- The crash was here
if (transform) {
result->transform = *transform;
}
return(result);
}
Now after searching hours of the culprit (in totally wrong places of course), i finally double checked the actual structure for storing the color:
union Vec4f {
struct {
union {
Vec3f xyz;
struct {
r32 x, y, z;
};
};
r32 w;
};
struct {
union {
Vec3f rgb;
struct {
r32 r, g, b;
};
};
r32 a;
};
struct {
Vec3f xyz;
r32 w;
};
struct {
Vec2f xy;
r32 ignored0;
r32 ignored1;
};
struct {
r32 ignored2;
Vec2f yz;
r32 ignored3;
};
struct {
r32 ignored4;
r32 ignored5;
Vec2f zw;
};
struct {
__m128 simd128;
};
r32 m[4];
};
What i missed here, was the __m128 which was used in the SSE implementation for several color corrections on a pixel level.
What i didn´t know about: __m128 must be aligned by a 16 byte boundary, otherwise you get undefined behaviors.
After removing the __m128 from the vector structure with introducing an additional _mm_load_ps() to get the color correction working - the issue was gone.
This was not easy to track down, it took my hours to figure this out... This was truly coding horror!
I really should sleep more...