Browse Source

Shaders: ensure the structures are 4-byte aligned.

pull/518/head
Vladimír Vondruš 5 years ago
parent
commit
b62f1903eb
  1. 4
      src/Magnum/Shaders/DistanceFieldVector.h
  2. 4
      src/Magnum/Shaders/MeshVisualizer.h
  3. 10
      src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp
  4. 8
      src/Magnum/Shaders/Test/FlatTest.cpp
  5. 16
      src/Magnum/Shaders/Test/GenericTest.cpp
  6. 12
      src/Magnum/Shaders/Test/MeshVisualizerTest.cpp
  7. 12
      src/Magnum/Shaders/Test/PhongTest.cpp
  8. 8
      src/Magnum/Shaders/Test/VectorTest.cpp

4
src/Magnum/Shaders/DistanceFieldVector.h

@ -108,7 +108,7 @@ struct DistanceFieldVectorDrawUniform {
/* This field is an UnsignedInt in the shader and materialId is extracted /* This field is an UnsignedInt in the shader and materialId is extracted
as (value & 0xffff), so the order has to be different on BE */ as (value & 0xffff), so the order has to be different on BE */
#ifndef CORRADE_TARGET_BIG_ENDIAN #ifndef CORRADE_TARGET_BIG_ENDIAN
UnsignedShort materialId; alignas(4) UnsignedShort materialId;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK /* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */ I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
@ -119,7 +119,7 @@ struct DistanceFieldVectorDrawUniform {
:16; /* reserved for skinOffset */ :16; /* reserved for skinOffset */
#endif #endif
#else #else
UnsignedShort alignas(4) UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8) #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 */ _pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif #endif

4
src/Magnum/Shaders/MeshVisualizer.h

@ -107,7 +107,7 @@ struct MeshVisualizerDrawUniform2D {
/* This field is an UnsignedInt in the shader and materialId is extracted /* This field is an UnsignedInt in the shader and materialId is extracted
as (value & 0xffff), so the order has to be different on BE */ as (value & 0xffff), so the order has to be different on BE */
#ifndef CORRADE_TARGET_BIG_ENDIAN #ifndef CORRADE_TARGET_BIG_ENDIAN
UnsignedShort materialId; alignas(4) UnsignedShort materialId;
/* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK /* warning: Member __pad0__ is not documented. FFS DOXYGEN WHY DO YOU THINK
I MADE THOSE UNNAMED, YOU DUMB FOOL */ I MADE THOSE UNNAMED, YOU DUMB FOOL */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
@ -118,7 +118,7 @@ struct MeshVisualizerDrawUniform2D {
:16; /* reserved for skinOffset */ :16; /* reserved for skinOffset */
#endif #endif
#else #else
UnsignedShort alignas(4) UnsignedShort
#if (defined(CORRADE_TARGET_CLANG) && __clang_major__ < 4) || (defined(CORRADE_TARGET_APPLE_CLANG) && __clang_major__ < 8) #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 */ _pad0 /* Otherwise it refuses to constexpr, on 3.8 at least */
#endif #endif

10
src/Magnum/Shaders/Test/DistanceFieldVectorTest.cpp

@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct DistanceFieldVectorTest: TestSuite::Tester { struct DistanceFieldVectorTest: TestSuite::Tester {
explicit DistanceFieldVectorTest(); explicit DistanceFieldVectorTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void drawUniformConstructDefault(); void drawUniformConstructDefault();
void drawUniformConstructNoInit(); void drawUniformConstructNoInit();
@ -46,8 +46,8 @@ struct DistanceFieldVectorTest: TestSuite::Tester {
}; };
DistanceFieldVectorTest::DistanceFieldVectorTest() { DistanceFieldVectorTest::DistanceFieldVectorTest() {
addTests({&DistanceFieldVectorTest::uniformSize<DistanceFieldVectorDrawUniform>, addTests({&DistanceFieldVectorTest::uniformSizeAlignment<DistanceFieldVectorDrawUniform>,
&DistanceFieldVectorTest::uniformSize<DistanceFieldVectorMaterialUniform>, &DistanceFieldVectorTest::uniformSizeAlignment<DistanceFieldVectorMaterialUniform>,
&DistanceFieldVectorTest::drawUniformConstructDefault, &DistanceFieldVectorTest::drawUniformConstructDefault,
&DistanceFieldVectorTest::drawUniformConstructNoInit, &DistanceFieldVectorTest::drawUniformConstructNoInit,
@ -69,7 +69,7 @@ template<> struct UniformTraits<DistanceFieldVectorMaterialUniform> {
static const char* name() { return "DistanceFieldVectorMaterialUniform"; } static const char* name() { return "DistanceFieldVectorMaterialUniform"; }
}; };
template<class T> void DistanceFieldVectorTest::uniformSize() { template<class T> void DistanceFieldVectorTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment.");
@ -79,6 +79,8 @@ template<class T> void DistanceFieldVectorTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment.");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768.");
CORRADE_COMPARE(alignof(T), 4);
} }
void DistanceFieldVectorTest::drawUniformConstructDefault() { void DistanceFieldVectorTest::drawUniformConstructDefault() {

8
src/Magnum/Shaders/Test/FlatTest.cpp

@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct FlatTest: TestSuite::Tester { struct FlatTest: TestSuite::Tester {
explicit FlatTest(); explicit FlatTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void drawUniformConstructDefault(); void drawUniformConstructDefault();
void drawUniformConstructNoInit(); void drawUniformConstructNoInit();
@ -41,7 +41,7 @@ struct FlatTest: TestSuite::Tester {
}; };
FlatTest::FlatTest() { FlatTest::FlatTest() {
addTests({&FlatTest::uniformSize<FlatDrawUniform>, addTests({&FlatTest::uniformSizeAlignment<FlatDrawUniform>,
&FlatTest::drawUniformConstructDefault, &FlatTest::drawUniformConstructDefault,
&FlatTest::drawUniformConstructNoInit, &FlatTest::drawUniformConstructNoInit,
@ -55,7 +55,7 @@ template<> struct UniformTraits<FlatDrawUniform> {
static const char* name() { return "FlatDrawUniform"; } static const char* name() { return "FlatDrawUniform"; }
}; };
template<class T> void FlatTest::uniformSize() { template<class T> void FlatTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment.");
@ -65,6 +65,8 @@ template<class T> void FlatTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment.");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768.");
CORRADE_COMPARE(alignof(T), 4);
} }
void FlatTest::drawUniformConstructDefault() { void FlatTest::drawUniformConstructDefault() {

16
src/Magnum/Shaders/Test/GenericTest.cpp

@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct GenericTest: TestSuite::Tester { struct GenericTest: TestSuite::Tester {
explicit GenericTest(); explicit GenericTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void projectionUniform2DConstructDefault(); void projectionUniform2DConstructDefault();
void projectionUniform2DConstructNoInit(); void projectionUniform2DConstructNoInit();
@ -57,11 +57,11 @@ struct GenericTest: TestSuite::Tester {
}; };
GenericTest::GenericTest() { GenericTest::GenericTest() {
addTests({&GenericTest::uniformSize<ProjectionUniform2D>, addTests({&GenericTest::uniformSizeAlignment<ProjectionUniform2D>,
&GenericTest::uniformSize<ProjectionUniform3D>, &GenericTest::uniformSizeAlignment<ProjectionUniform3D>,
&GenericTest::uniformSize<TransformationUniform2D>, &GenericTest::uniformSizeAlignment<TransformationUniform2D>,
&GenericTest::uniformSize<TransformationUniform3D>, &GenericTest::uniformSizeAlignment<TransformationUniform3D>,
&GenericTest::uniformSize<TextureTransformationUniform>, &GenericTest::uniformSizeAlignment<TextureTransformationUniform>,
&GenericTest::projectionUniform2DConstructDefault, &GenericTest::projectionUniform2DConstructDefault,
&GenericTest::projectionUniform2DConstructNoInit, &GenericTest::projectionUniform2DConstructNoInit,
@ -103,7 +103,7 @@ template<> struct UniformTraits<TextureTransformationUniform> {
static const char* name() { return "TextureTransformationUniform"; } static const char* name() { return "TextureTransformationUniform"; }
}; };
template<class T> void GenericTest::uniformSize() { template<class T> void GenericTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment.");
@ -113,6 +113,8 @@ template<class T> void GenericTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment.");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768.");
CORRADE_COMPARE(alignof(T), 4);
} }
void GenericTest::projectionUniform2DConstructDefault() { void GenericTest::projectionUniform2DConstructDefault() {

12
src/Magnum/Shaders/Test/MeshVisualizerTest.cpp

@ -34,7 +34,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct MeshVisualizerTest: TestSuite::Tester { struct MeshVisualizerTest: TestSuite::Tester {
explicit MeshVisualizerTest(); explicit MeshVisualizerTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void drawUniform2DConstructDefault(); void drawUniform2DConstructDefault();
void drawUniform2DConstructNoInit(); void drawUniform2DConstructNoInit();
@ -52,9 +52,9 @@ struct MeshVisualizerTest: TestSuite::Tester {
}; };
MeshVisualizerTest::MeshVisualizerTest() { MeshVisualizerTest::MeshVisualizerTest() {
addTests({&MeshVisualizerTest::uniformSize<MeshVisualizerDrawUniform2D>, addTests({&MeshVisualizerTest::uniformSizeAlignment<MeshVisualizerDrawUniform2D>,
&MeshVisualizerTest::uniformSize<MeshVisualizerDrawUniform3D>, &MeshVisualizerTest::uniformSizeAlignment<MeshVisualizerDrawUniform3D>,
&MeshVisualizerTest::uniformSize<MeshVisualizerMaterialUniform>, &MeshVisualizerTest::uniformSizeAlignment<MeshVisualizerMaterialUniform>,
&MeshVisualizerTest::drawUniform2DConstructDefault, &MeshVisualizerTest::drawUniform2DConstructDefault,
&MeshVisualizerTest::drawUniform2DConstructNoInit, &MeshVisualizerTest::drawUniform2DConstructNoInit,
@ -84,7 +84,7 @@ template<> struct UniformTraits<MeshVisualizerMaterialUniform> {
static const char* name() { return "MeshVisualizerMaterialUniform"; } static const char* name() { return "MeshVisualizerMaterialUniform"; }
}; };
template<class T> void MeshVisualizerTest::uniformSize() { template<class T> void MeshVisualizerTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment"); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment");
@ -94,6 +94,8 @@ template<class T> void MeshVisualizerTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment"); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768"); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768");
CORRADE_COMPARE(alignof(T), 4);
} }
void MeshVisualizerTest::drawUniform2DConstructDefault() { void MeshVisualizerTest::drawUniform2DConstructDefault() {

12
src/Magnum/Shaders/Test/PhongTest.cpp

@ -34,7 +34,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct PhongTest: TestSuite::Tester { struct PhongTest: TestSuite::Tester {
explicit PhongTest(); explicit PhongTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void drawUniformConstructDefault(); void drawUniformConstructDefault();
void drawUniformConstructNoInit(); void drawUniformConstructNoInit();
@ -51,9 +51,9 @@ struct PhongTest: TestSuite::Tester {
}; };
PhongTest::PhongTest() { PhongTest::PhongTest() {
addTests({&PhongTest::uniformSize<PhongDrawUniform>, addTests({&PhongTest::uniformSizeAlignment<PhongDrawUniform>,
&PhongTest::uniformSize<PhongMaterialUniform>, &PhongTest::uniformSizeAlignment<PhongMaterialUniform>,
&PhongTest::uniformSize<PhongLightUniform>, &PhongTest::uniformSizeAlignment<PhongLightUniform>,
&PhongTest::drawUniformConstructDefault, &PhongTest::drawUniformConstructDefault,
&PhongTest::drawUniformConstructNoInit, &PhongTest::drawUniformConstructNoInit,
@ -82,7 +82,7 @@ template<> struct UniformTraits<PhongLightUniform> {
static const char* name() { return "PhongLightUniform"; } static const char* name() { return "PhongLightUniform"; }
}; };
template<class T> void PhongTest::uniformSize() { template<class T> void PhongTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment.");
@ -92,6 +92,8 @@ template<class T> void PhongTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment.");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768.");
CORRADE_COMPARE(alignof(T), 4);
} }
void PhongTest::drawUniformConstructDefault() { void PhongTest::drawUniformConstructDefault() {

8
src/Magnum/Shaders/Test/VectorTest.cpp

@ -33,7 +33,7 @@ namespace Magnum { namespace Shaders { namespace Test { namespace {
struct VectorTest: TestSuite::Tester { struct VectorTest: TestSuite::Tester {
explicit VectorTest(); explicit VectorTest();
template<class T> void uniformSize(); template<class T> void uniformSizeAlignment();
void drawUniformConstructDefault(); void drawUniformConstructDefault();
void drawUniformConstructNoInit(); void drawUniformConstructNoInit();
@ -41,7 +41,7 @@ struct VectorTest: TestSuite::Tester {
}; };
VectorTest::VectorTest() { VectorTest::VectorTest() {
addTests({&VectorTest::uniformSize<VectorDrawUniform>, addTests({&VectorTest::uniformSizeAlignment<VectorDrawUniform>,
&VectorTest::drawUniformConstructDefault, &VectorTest::drawUniformConstructDefault,
&VectorTest::drawUniformConstructNoInit, &VectorTest::drawUniformConstructNoInit,
@ -55,7 +55,7 @@ template<> struct UniformTraits<VectorDrawUniform> {
static const char* name() { return "VectorDrawUniform"; } static const char* name() { return "VectorDrawUniform"; }
}; };
template<class T> void VectorTest::uniformSize() { template<class T> void VectorTest::uniformSizeAlignment() {
setTestCaseTemplateName(UniformTraits<T>::name()); setTestCaseTemplateName(UniformTraits<T>::name());
CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment."); CORRADE_FAIL_IF(sizeof(T) % sizeof(Vector4) != 0, sizeof(T) << "is not a multiple of vec4 for UBO alignment.");
@ -65,6 +65,8 @@ template<class T> void VectorTest::uniformSize() {
CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment."); CORRADE_FAIL_IF(768 % sizeof(T) != 0, sizeof(T) << "can't fit exactly into 768-byte UBO alignment.");
if(256 % sizeof(T) != 0) if(256 % sizeof(T) != 0)
CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768."); CORRADE_WARN(sizeof(T) << "can't fit exactly into 256-byte UBO alignment, only 768.");
CORRADE_COMPARE(alignof(T), 4);
} }
void VectorTest::drawUniformConstructDefault() { void VectorTest::drawUniformConstructDefault() {

Loading…
Cancel
Save