From b62f1903ebfa838a67b33d30c72f374d9188c737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 21 May 2021 17:21:26 +0200 Subject: [PATCH] Shaders: ensure the structures are 4-byte aligned. --- src/Magnum/Shaders/DistanceFieldVector.h | 4 ++-- src/Magnum/Shaders/MeshVisualizer.h | 4 ++-- .../Shaders/Test/DistanceFieldVectorTest.cpp | 10 ++++++---- src/Magnum/Shaders/Test/FlatTest.cpp | 8 +++++--- src/Magnum/Shaders/Test/GenericTest.cpp | 16 +++++++++------- src/Magnum/Shaders/Test/MeshVisualizerTest.cpp | 12 +++++++----- src/Magnum/Shaders/Test/PhongTest.cpp | 12 +++++++----- src/Magnum/Shaders/Test/VectorTest.cpp | 8 +++++--- 8 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/Magnum/Shaders/DistanceFieldVector.h b/src/Magnum/Shaders/DistanceFieldVector.h index a6c452aa1..8964793d7 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.h +++ b/src/Magnum/Shaders/DistanceFieldVector.h @@ -108,7 +108,7 @@ struct DistanceFieldVectorDrawUniform { /* This field is an UnsignedInt in the shader and materialId is extracted as (value & 0xffff), so the order has to be different on BE */ #ifndef CORRADE_TARGET_BIG_ENDIAN - UnsignedShort materialId; + alignas(4) UnsignedShort materialId; /* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK I MADE THOSE UNNAMED, YOU DUMB FOOL */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -119,7 +119,7 @@ struct DistanceFieldVectorDrawUniform { :16; /* reserved for skinOffset */ #endif #else - UnsignedShort + alignas(4) UnsignedShort #if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8) _pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */ #endif diff --git a/src/Magnum/Shaders/MeshVisualizer.h b/src/Magnum/Shaders/MeshVisualizer.h index 2441daae1..2e4038412 100644 --- a/src/Magnum/Shaders/MeshVisualizer.h +++ b/src/Magnum/Shaders/MeshVisualizer.h @@ -107,7 +107,7 @@ struct MeshVisualizerDrawUniform2D { /* This field is an UnsignedInt in the shader and materialId is extracted as (value & 0xffff), so the order has to be different on BE */ #ifndef CORRADE_TARGET_BIG_ENDIAN - UnsignedShort materialId; + alignas(4) UnsignedShort materialId; /* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK I MADE THOSE UNNAMED, YOU DUMB FOOL */ #ifndef DOXYGEN_GENERATING_OUTPUT @@ -118,7 +118,7 @@ struct MeshVisualizerDrawUniform2D { :16; /* reserved for skinOffset */ #endif #else - UnsignedShort + alignas(4) UnsignedShort #if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8) _pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */ #endif diff --git a/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp b/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp index 5ec7a4c8f..768591731 100644 --- a/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp +++ b/src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp @@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct DistanceFieldVectorTest: TestSuite::Tester { explicit DistanceFieldVectorTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void drawUniformConstructDefault(); void drawUniformConstructNoInit(); @@ -46,8 +46,8 @@ struct DistanceFieldVectorTest: TestSuite::Tester { }; DistanceFieldVectorTest::DistanceFieldVectorTest() { - addTests({&DistanceFieldVectorTest::uniformSize, - &DistanceFieldVectorTest::uniformSize, + addTests({&DistanceFieldVectorTest::uniformSizeAlignment, + &DistanceFieldVectorTest::uniformSizeAlignment, &DistanceFieldVectorTest::drawUniformConstructDefault, &DistanceFieldVectorTest::drawUniformConstructNoInit, @@ -69,7 +69,7 @@ template<> struct UniformTraits { static const char* name() { return "DistanceFieldVectorMaterialUniform"; } }; -template void DistanceFieldVectorTest::uniformSize() { +template void DistanceFieldVectorTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); @@ -79,6 +79,8 @@ template void DistanceFieldVectorTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); + + CORRADE_COMPARE(alignof(T), 4); } void DistanceFieldVectorTest::drawUniformConstructDefault() { diff --git a/src/Magnum/Shaders/Test/FlatTest.cpp b/src/Magnum/Shaders/Test/FlatTest.cpp index 1a5a86df3..3ab604d65 100644 --- a/src/Magnum/Shaders/Test/FlatTest.cpp +++ b/src/Magnum/Shaders/Test/FlatTest.cpp @@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct FlatTest: TestSuite::Tester { explicit FlatTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void drawUniformConstructDefault(); void drawUniformConstructNoInit(); @@ -41,7 +41,7 @@ struct FlatTest: TestSuite::Tester { }; FlatTest::FlatTest() { - addTests({&FlatTest::uniformSize, + addTests({&FlatTest::uniformSizeAlignment, &FlatTest::drawUniformConstructDefault, &FlatTest::drawUniformConstructNoInit, @@ -55,7 +55,7 @@ template<> struct UniformTraits { static const char* name() { return "FlatDrawUniform"; } }; -template void FlatTest::uniformSize() { +template void FlatTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); @@ -65,6 +65,8 @@ template void FlatTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); + + CORRADE_COMPARE(alignof(T), 4); } void FlatTest::drawUniformConstructDefault() { diff --git a/src/Magnum/Shaders/Test/GenericTest.cpp b/src/Magnum/Shaders/Test/GenericTest.cpp index f6a03fcea..0abd1809c 100644 --- a/src/Magnum/Shaders/Test/GenericTest.cpp +++ b/src/Magnum/Shaders/Test/GenericTest.cpp @@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct GenericTest: TestSuite::Tester { explicit GenericTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void projectionUniform2DConstructDefault(); void projectionUniform2DConstructNoInit(); @@ -57,11 +57,11 @@ struct GenericTest: TestSuite::Tester { }; GenericTest::GenericTest() { - addTests({&GenericTest::uniformSize, - &GenericTest::uniformSize, - &GenericTest::uniformSize, - &GenericTest::uniformSize, - &GenericTest::uniformSize, + addTests({&GenericTest::uniformSizeAlignment, + &GenericTest::uniformSizeAlignment, + &GenericTest::uniformSizeAlignment, + &GenericTest::uniformSizeAlignment, + &GenericTest::uniformSizeAlignment, &GenericTest::projectionUniform2DConstructDefault, &GenericTest::projectionUniform2DConstructNoInit, @@ -103,7 +103,7 @@ template<> struct UniformTraits { static const char* name() { return "TextureTransformationUniform"; } }; -template void GenericTest::uniformSize() { +template void GenericTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); @@ -113,6 +113,8 @@ template void GenericTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); + + CORRADE_COMPARE(alignof(T), 4); } void GenericTest::projectionUniform2DConstructDefault() { diff --git a/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp b/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp index e6abe8c6a..178c261e5 100644 --- a/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp +++ b/src/Magnum/Shaders/Test/MeshVisualizerTest.cpp @@ -34,7 +34,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct MeshVisualizerTest: TestSuite::Tester { explicit MeshVisualizerTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void drawUniform2DConstructDefault(); void drawUniform2DConstructNoInit(); @@ -52,9 +52,9 @@ struct MeshVisualizerTest: TestSuite::Tester { }; MeshVisualizerTest::MeshVisualizerTest() { - addTests({&MeshVisualizerTest::uniformSize, - &MeshVisualizerTest::uniformSize, - &MeshVisualizerTest::uniformSize, + addTests({&MeshVisualizerTest::uniformSizeAlignment, + &MeshVisualizerTest::uniformSizeAlignment, + &MeshVisualizerTest::uniformSizeAlignment, &MeshVisualizerTest::drawUniform2DConstructDefault, &MeshVisualizerTest::drawUniform2DConstructNoInit, @@ -84,7 +84,7 @@ template<> struct UniformTraits { static const char* name() { return "MeshVisualizerMaterialUniform"; } }; -template void MeshVisualizerTest::uniformSize() { +template void MeshVisualizerTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment"); @@ -94,6 +94,8 @@ template void MeshVisualizerTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment"); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768"); + + CORRADE_COMPARE(alignof(T), 4); } void MeshVisualizerTest::drawUniform2DConstructDefault() { diff --git a/src/Magnum/Shaders/Test/PhongTest.cpp b/src/Magnum/Shaders/Test/PhongTest.cpp index e29330d3b..510da0a51 100644 --- a/src/Magnum/Shaders/Test/PhongTest.cpp +++ b/src/Magnum/Shaders/Test/PhongTest.cpp @@ -34,7 +34,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct PhongTest: TestSuite::Tester { explicit PhongTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void drawUniformConstructDefault(); void drawUniformConstructNoInit(); @@ -51,9 +51,9 @@ struct PhongTest: TestSuite::Tester { }; PhongTest::PhongTest() { - addTests({&PhongTest::uniformSize, - &PhongTest::uniformSize, - &PhongTest::uniformSize, + addTests({&PhongTest::uniformSizeAlignment, + &PhongTest::uniformSizeAlignment, + &PhongTest::uniformSizeAlignment, &PhongTest::drawUniformConstructDefault, &PhongTest::drawUniformConstructNoInit, @@ -82,7 +82,7 @@ template<> struct UniformTraits { static const char* name() { return "PhongLightUniform"; } }; -template void PhongTest::uniformSize() { +template void PhongTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); @@ -92,6 +92,8 @@ template void PhongTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); + + CORRADE_COMPARE(alignof(T), 4); } void PhongTest::drawUniformConstructDefault() { diff --git a/src/Magnum/Shaders/Test/VectorTest.cpp b/src/Magnum/Shaders/Test/VectorTest.cpp index b3e49cd2b..fffb94115 100644 --- a/src/Magnum/Shaders/Test/VectorTest.cpp +++ b/src/Magnum/Shaders/Test/VectorTest.cpp @@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace { struct VectorTest: TestSuite::Tester { explicit VectorTest(); - template void uniformSize(); + template void uniformSizeAlignment(); void drawUniformConstructDefault(); void drawUniformConstructNoInit(); @@ -41,7 +41,7 @@ struct VectorTest: TestSuite::Tester { }; VectorTest::VectorTest() { - addTests({&VectorTest::uniformSize, + addTests({&VectorTest::uniformSizeAlignment, &VectorTest::drawUniformConstructDefault, &VectorTest::drawUniformConstructNoInit, @@ -55,7 +55,7 @@ template<> struct UniformTraits { static const char* name() { return "VectorDrawUniform"; } }; -template void VectorTest::uniformSize() { +template void VectorTest::uniformSizeAlignment() { setTestCaseTemplateName(UniformTraits::name()); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); @@ -65,6 +65,8 @@ template void VectorTest::uniformSize() { CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); if(256 % sizeof(T) != 0) CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); + + CORRADE_COMPARE(alignof(T), 4); } void VectorTest::drawUniformConstructDefault() {