From fd3bd7e7377e04b407ab4660052e297280dcd2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 8 Jun 2021 11:32:04 +0200 Subject: [PATCH] Shaders: ANGLE, for fucks sake! --- src/Magnum/Shaders/Flat.vert | 20 ++++++++++---------- src/Magnum/Shaders/MeshVisualizer.frag | 3 ++- src/Magnum/Shaders/MeshVisualizer.geom | 3 ++- src/Magnum/Shaders/MeshVisualizer.vert | 11 +++++++---- src/Magnum/Shaders/Phong.frag | 3 ++- src/Magnum/Shaders/Phong.vert | 17 +++++++++++++++-- src/Magnum/Shaders/Vector.vert | 20 ++++++++++---------- src/Magnum/Shaders/VertexColor.vert | 20 ++++++++++---------- 8 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/Magnum/Shaders/Flat.vert b/src/Magnum/Shaders/Flat.vert index dfae3fcf1..eb71c6730 100644 --- a/src/Magnum/Shaders/Flat.vert +++ b/src/Magnum/Shaders/Flat.vert @@ -112,7 +112,9 @@ layout(std140 ) uniform TransformationProjection { highp #ifdef TWO_DIMENSIONS - mat3 + /* Can't be a mat3 because of ANGLE, see DrawUniform in Phong.vert for + details */ + mat3x4 #elif defined(THREE_DIMENSIONS) mat4 #else @@ -237,15 +239,13 @@ void main() { #define drawId drawOffset #endif - highp const - #ifdef TWO_DIMENSIONS - mat3 - #elif defined(THREE_DIMENSIONS) - mat4 - #else - #error - #endif - transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #ifdef TWO_DIMENSIONS + highp const mat3 transformationProjectionMatrix = mat3(transformationProjectionMatrices[drawId]); + #elif defined(THREE_DIMENSIONS) + highp const mat4 transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #else + #error + #endif #ifdef TEXTURE_TRANSFORMATION mediump const mat3 textureMatrix = mat3(textureTransformations[drawId].rotationScaling.xy, 0.0, textureTransformations[drawId].rotationScaling.zw, 0.0, textureTransformations[drawId].textureTransformation_offset, 1.0); #ifdef TEXTURE_ARRAYS diff --git a/src/Magnum/Shaders/MeshVisualizer.frag b/src/Magnum/Shaders/MeshVisualizer.frag index d1e467052..db16422a8 100644 --- a/src/Magnum/Shaders/MeshVisualizer.frag +++ b/src/Magnum/Shaders/MeshVisualizer.frag @@ -131,7 +131,8 @@ uniform highp uint drawOffset always before any code. */ struct DrawUniform { #ifdef THREE_DIMENSIONS - highp mat3 normalMatrix; /* actually mat3x4 */ + /* Can't be a mat3 because of ANGLE, see Phong.vert for details */ + highp mat3x4 normalMatrix; #elif !defined(TWO_DIMENSIONS) #error #endif diff --git a/src/Magnum/Shaders/MeshVisualizer.geom b/src/Magnum/Shaders/MeshVisualizer.geom index 3cfe14402..ac662e2ad 100644 --- a/src/Magnum/Shaders/MeshVisualizer.geom +++ b/src/Magnum/Shaders/MeshVisualizer.geom @@ -103,7 +103,8 @@ uniform highp uint drawOffset always before any code. */ struct DrawUniform { #ifdef THREE_DIMENSIONS - highp mat3 normalMatrix; /* actually mat3x4 */ + /* Can't be a mat3 because of ANGLE, see Phong.vert for details */ + highp mat3x4 normalMatrix; #elif !defined(TWO_DIMENSIONS) #error #endif diff --git a/src/Magnum/Shaders/MeshVisualizer.vert b/src/Magnum/Shaders/MeshVisualizer.vert index c0e514e75..43359b178 100644 --- a/src/Magnum/Shaders/MeshVisualizer.vert +++ b/src/Magnum/Shaders/MeshVisualizer.vert @@ -132,7 +132,9 @@ layout(std140 , binding = 1 #endif ) uniform TransformationProjection { - highp mat3 transformationProjectionMatrices[DRAW_COUNT]; + /* Can't be a mat3 because of ANGLE, see DrawUniform in Phong.vert for + details */ + highp mat3x4 transformationProjectionMatrices[DRAW_COUNT]; }; #elif defined(THREE_DIMENSIONS) layout(std140 @@ -159,7 +161,8 @@ layout(std140 always before any code. */ struct DrawUniform { #ifdef THREE_DIMENSIONS - highp mat3 normalMatrix; /* actually mat3x4 */ + /* Can't be a mat3 because of ANGLE, see Phong.vert for details */ + highp mat3x4 normalMatrix; #elif !defined(TWO_DIMENSIONS) #error #endif @@ -322,14 +325,14 @@ void main() { #endif #ifdef TWO_DIMENSIONS - highp const mat3 transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + highp const mat3 transformationProjectionMatrix = mat3(transformationProjectionMatrices[drawId]); #elif defined(THREE_DIMENSIONS) highp const mat4 transformationMatrix = transformationMatrices[drawId]; #else #error #endif #if defined(TANGENT_DIRECTION) || defined(BITANGENT_DIRECTION) || defined(BITANGENT_FROM_TANGENT_DIRECTION) || defined(NORMAL_DIRECTION) - mediump const mat3 normalMatrix = draws[drawId].normalMatrix; + mediump const mat3 normalMatrix = mat3(draws[drawId].normalMatrix); #endif mediump const uint materialId = draws[drawId].draw_materialIdReserved & 0xffffu; lowp float colorMapOffset = materials[materialId].material_colorMapOffset; diff --git a/src/Magnum/Shaders/Phong.frag b/src/Magnum/Shaders/Phong.frag index ccfb8371a..42e05b121 100644 --- a/src/Magnum/Shaders/Phong.frag +++ b/src/Magnum/Shaders/Phong.frag @@ -167,7 +167,8 @@ uniform highp uint drawOffset /* Keep in sync with Phong.vert. Can't "outsource" to a common file because the #extension directive needs to be always before any code. */ struct DrawUniform { - mediump mat3 normalMatrix; /* actually mat3x4 */ + /* Can't be a mat3 because of ANGLE, see Phong.vert for details */ + mediump mat3x4 normalMatrix; highp uvec4 materialIdReservedObjectIdLightOffsetLightCount; #define draw_materialIdReserved materialIdReservedObjectIdLightOffsetLightCount.x #define draw_objectId materialIdReservedObjectIdLightOffsetLightCount.y diff --git a/src/Magnum/Shaders/Phong.vert b/src/Magnum/Shaders/Phong.vert index 521c55389..2769fa980 100644 --- a/src/Magnum/Shaders/Phong.vert +++ b/src/Magnum/Shaders/Phong.vert @@ -130,7 +130,20 @@ uniform highp uint drawOffset /* Keep in sync with Phong.frag. Can't "outsource" to a common file because the #extension directive needs to be always before any code. */ struct DrawUniform { - mediump mat3 normalMatrix; /* actually mat3x4 */ + /* Of all drivers, I made the crucial mistake of expecting ANGLE to have + non-broken uniform packing. Of course everything including random phone + drivers worked, except ANGLE with a D3D backend, which blew up when + seeing `mat3` here. With all the coding guidelines, rules and automated + bullying from Clang Tidy in place over at Google, it seems the false + sense of security is so strong that they don't even bother testing what + they wrote. Or, how to code, the Google way: + + 1. Thoroughly document the packing rules and how the translation of + every GLSL type to the D3D equivalent is performed: + https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/libANGLE/renderer/d3d/d3d11/UniformBlockToStructuredBufferTranslation.md#std140-limitation + 2. Forget to actually implement and test the damn thing. + */ + mediump mat3x4 normalMatrix; highp uvec4 materialIdReservedObjectIdLightOffsetLightCount; #define draw_materialIdReserved materialIdReservedObjectIdLightOffsetLightCount.x #define draw_objectId materialIdReservedObjectIdLightOffsetLightCount.y @@ -336,7 +349,7 @@ void main() { highp const mat4 transformationMatrix = transformationMatrices[drawId]; #if LIGHT_COUNT - mediump const mat3 normalMatrix = draws[drawId].normalMatrix; + mediump const mat3 normalMatrix = mat3(draws[drawId].normalMatrix); #endif #ifdef TEXTURE_TRANSFORMATION mediump const mat3 textureMatrix = mat3(textureTransformations[drawId].rotationScaling.xy, 0.0, textureTransformations[drawId].rotationScaling.zw, 0.0, textureTransformations[drawId].textureTransformation_offset, 1.0); diff --git a/src/Magnum/Shaders/Vector.vert b/src/Magnum/Shaders/Vector.vert index f92fe714b..c0acfe667 100644 --- a/src/Magnum/Shaders/Vector.vert +++ b/src/Magnum/Shaders/Vector.vert @@ -96,7 +96,9 @@ layout(std140 ) uniform TransformationProjection { highp #ifdef TWO_DIMENSIONS - mat3 + /* Can't be a mat3 because of ANGLE, see DrawUniform in Phong.vert for + details */ + mat3x4 #elif defined(THREE_DIMENSIONS) mat4 #else @@ -162,15 +164,13 @@ void main() { #define drawId drawOffset #endif - highp const - #ifdef TWO_DIMENSIONS - mat3 - #elif defined(THREE_DIMENSIONS) - mat4 - #else - #error - #endif - transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #ifdef TWO_DIMENSIONS + highp const mat3 transformationProjectionMatrix = mat3(transformationProjectionMatrices[drawId]); + #elif defined(THREE_DIMENSIONS) + highp const mat4 transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #else + #error + #endif #ifdef TEXTURE_TRANSFORMATION mediump const mat3 textureMatrix = mat3(textureTransformations[drawId].rotationScaling.xy, 0.0, textureTransformations[drawId].rotationScaling.zw, 0.0, textureTransformations[drawId].textureTransformation_offset, 1.0); #endif diff --git a/src/Magnum/Shaders/VertexColor.vert b/src/Magnum/Shaders/VertexColor.vert index d1fbceea0..9c16869b6 100644 --- a/src/Magnum/Shaders/VertexColor.vert +++ b/src/Magnum/Shaders/VertexColor.vert @@ -85,7 +85,9 @@ layout(std140 ) uniform TransformationProjection { highp #ifdef TWO_DIMENSIONS - mat3 + /* Can't be a mat3 because of ANGLE, see DrawUniform in Phong.vert for + details */ + mat3x4 #elif defined(THREE_DIMENSIONS) mat4 #else @@ -131,15 +133,13 @@ void main() { #define drawId drawOffset #endif - highp const - #ifdef TWO_DIMENSIONS - mat3 - #elif defined(THREE_DIMENSIONS) - mat4 - #else - #error - #endif - transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #ifdef TWO_DIMENSIONS + highp const mat3 transformationProjectionMatrix = mat3(transformationProjectionMatrices[drawId]); + #elif defined(THREE_DIMENSIONS) + highp const mat4 transformationProjectionMatrix = transformationProjectionMatrices[drawId]; + #else + #error + #endif #endif #ifdef TWO_DIMENSIONS