From 8153adbc1c436ee74338a3eb531dcc086a1f07ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 13 Mar 2023 16:27:24 +0100 Subject: [PATCH] Shaders: don't format & pass _LOCATION defines on ES < 3.1 and WebGL. Saves quite a few unnecessary allocations and string operations. --- src/Magnum/Shaders/DistanceFieldVectorGL.cpp | 6 ++- src/Magnum/Shaders/FlatGL.cpp | 32 +++++++++++-- src/Magnum/Shaders/LineGL.cpp | 7 +-- src/Magnum/Shaders/MeshVisualizerGL.cpp | 41 +++++++++++++--- src/Magnum/Shaders/MeshVisualizerGL.h | 5 +- src/Magnum/Shaders/PhongGL.cpp | 50 +++++++++++++++++--- src/Magnum/Shaders/PhongGL.h | 4 +- src/Magnum/Shaders/VectorGL.cpp | 6 ++- src/Magnum/Shaders/VertexColorGL.cpp | 6 ++- src/Magnum/TextureTools/DistanceField.cpp | 6 ++- 10 files changed, 136 insertions(+), 27 deletions(-) diff --git a/src/Magnum/Shaders/DistanceFieldVectorGL.cpp b/src/Magnum/Shaders/DistanceFieldVectorGL.cpp index a9c5e5219..63bed096d 100644 --- a/src/Magnum/Shaders/DistanceFieldVectorGL.cpp +++ b/src/Magnum/Shaders/DistanceFieldVectorGL.cpp @@ -103,7 +103,11 @@ template typename DistanceFieldVectorGL::Com #ifndef MAGNUM_TARGET_GLES const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version version = context.supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif GL::Shader vert = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Vertex); diff --git a/src/Magnum/Shaders/FlatGL.cpp b/src/Magnum/Shaders/FlatGL.cpp index 841e3a721..4264a6983 100644 --- a/src/Magnum/Shaders/FlatGL.cpp +++ b/src/Magnum/Shaders/FlatGL.cpp @@ -144,7 +144,11 @@ template typename FlatGL::CompileState FlatG #ifndef MAGNUM_TARGET_GLES const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version version = context.supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif FlatGL out{NoInit}; @@ -179,6 +183,13 @@ template typename FlatGL::CompileState FlatG .addSource(configuration.flags() >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n"_s : ""_s); #ifndef MAGNUM_TARGET_GLES2 if(configuration.perVertexJointCount() || configuration.secondaryPerVertexJointCount()) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION are needed only in the non-UBO case if explicit + uniform location (desktop / ES3.1) is supported, and _INITIALIZER is + desktop only, so don't even have this branch on WebGL. OTOH, + branching on explicit uniform location support and adding just the + _INITIALIZER if not wouldn't really save much (have to format() + anyway), so passing them always. */ if(!(configuration.flags() >= Flag::UniformBuffers)) { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" @@ -195,7 +206,9 @@ template typename FlatGL::CompileState FlatG ((dimensions == 2 ? "mat3(1.0), "_s : "mat4(1.0), "_s)*configuration.jointCount()).exceptSuffix(2), #endif out._perInstanceJointCountUniform)); - } else { + } else + #endif + { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" "#define PER_VERTEX_JOINT_COUNT {}u\n" @@ -206,12 +219,23 @@ template typename FlatGL::CompileState FlatG } } if(configuration.flags() >= Flag::DynamicPerVertexJointCount) { - if(!(configuration.flags() >= Flag::UniformBuffers)) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION is needed only if explicit uniform location (desktop / + ES3.1) is supported, a plain string can be added otherwise. This is + an immediate uniform also in the UBO case. */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported(version)) + #else + if(version >= GL::Version::GLES310) + #endif + { vert.addSource(Utility::format( "#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n" "#define PER_VERTEX_JOINT_COUNT_LOCATION {}\n", out._perVertexJointCountUniform)); - } else { + } else + #endif + { vert.addSource("#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n"_s); } } diff --git a/src/Magnum/Shaders/LineGL.cpp b/src/Magnum/Shaders/LineGL.cpp index ccf7b6dde..c28f318a5 100644 --- a/src/Magnum/Shaders/LineGL.cpp +++ b/src/Magnum/Shaders/LineGL.cpp @@ -92,12 +92,13 @@ template typename LineGL::CompileState LineG #endif Utility::Resource rs{"MagnumShadersGL"_s}; - const GL::Context& context = GL::Context::current(); - #ifndef MAGNUM_TARGET_GLES + const GL::Context& context = GL::Context::current(); const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); + #elif !defined(MAGNUM_TARGET_WEBGL) + const GL::Version version = GL::Context::current().supportedVersion({GL::Version::GLES310, GL::Version::GLES300}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300}); + constexpr GL::Version version = GL::Version::GLES300; #endif /* Cap and join style is needed by both the vertex and fragment shader, diff --git a/src/Magnum/Shaders/MeshVisualizerGL.cpp b/src/Magnum/Shaders/MeshVisualizerGL.cpp index a244d5c29..b90bf5f45 100644 --- a/src/Magnum/Shaders/MeshVisualizerGL.cpp +++ b/src/Magnum/Shaders/MeshVisualizerGL.cpp @@ -157,7 +157,10 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra #ifndef MAGNUM_TARGET_GLES dimensions /* used for a uniform initializer, which isn't on GLSL ES */ #endif - , const UnsignedInt jointCount, const UnsignedInt perVertexJointCount, const UnsignedInt secondaryPerVertexJointCount, const UnsignedInt materialCount, const UnsignedInt drawCount, const UnsignedInt perInstanceJointCountUniform, const UnsignedInt perVertexJointCountUniform + , const UnsignedInt jointCount, const UnsignedInt perVertexJointCount, const UnsignedInt secondaryPerVertexJointCount, const UnsignedInt materialCount, const UnsignedInt drawCount + #ifndef MAGNUM_TARGET_WEBGL + , const UnsignedInt perInstanceJointCountUniform, const UnsignedInt perVertexJointCountUniform + #endif #endif ) { GL::Context& context = GL::Context::current(); @@ -198,6 +201,13 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra ; #ifndef MAGNUM_TARGET_GLES2 if(perVertexJointCount || secondaryPerVertexJointCount) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION are needed only in the non-UBO case if explicit + uniform location (desktop / ES3.1) is supported, and _INITIALIZER is + desktop-only, so don't even have this branch on WebGL. OTOH, + branching on explicit uniform location support and adding just the + _INITIALIZER if not wouldn't really save much (have to format() + anyway), so passing them always. */ if(!(flags >= FlagBase::UniformBuffers)) { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" @@ -214,7 +224,9 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra ((dimensions == 2 ? "mat3(1.0), "_s : "mat4(1.0), "_s)*jointCount).exceptSuffix(2), #endif perInstanceJointCountUniform)); - } else { + } else + #endif + { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" "#define PER_VERTEX_JOINT_COUNT {}u\n" @@ -225,12 +237,23 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra } } if(flags >= FlagBase::DynamicPerVertexJointCount) { - if(!(flags >= FlagBase::UniformBuffers)) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION is needed only if explicit uniform location (desktop / + ES3.1) is supported, a plain string can be added otherwise. This is + an immediate uniform also in the UBO case. */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported(version)) + #else + if(version >= GL::Version::GLES310) + #endif + { vert.addSource(Utility::format( "#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n" "#define PER_VERTEX_JOINT_COUNT_LOCATION {}\n", perVertexJointCountUniform)); - } else { + } else + #endif + { vert.addSource("#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n"_s); } } @@ -514,7 +537,10 @@ MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(const Configuration GL::Shader frag{NoCreate}; const GL::Version version = setupShaders(vert, frag, rs, baseFlags #ifndef MAGNUM_TARGET_GLES2 - , 2, configuration.jointCount(), configuration.perVertexJointCount(), configuration.secondaryPerVertexJointCount(), configuration.materialCount(), configuration.drawCount(), out._perInstanceJointCountUniform, out._perVertexJointCountUniform + , 2, configuration.jointCount(), configuration.perVertexJointCount(), configuration.secondaryPerVertexJointCount(), configuration.materialCount(), configuration.drawCount() + #ifndef MAGNUM_TARGET_WEBGL + , out._perInstanceJointCountUniform, out._perVertexJointCountUniform + #endif #endif ); Containers::Optional geom; @@ -963,7 +989,10 @@ MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(const Configuration GL::Shader frag{NoCreate}; const GL::Version version = setupShaders(vert, frag, rs, baseFlags #ifndef MAGNUM_TARGET_GLES2 - , 3, configuration.jointCount(), configuration.perVertexJointCount(), configuration.secondaryPerVertexJointCount(), configuration.materialCount(), configuration.drawCount(), out._perInstanceJointCountUniform, out._perVertexJointCountUniform + , 3, configuration.jointCount(), configuration.perVertexJointCount(), configuration.secondaryPerVertexJointCount(), configuration.materialCount(), configuration.drawCount() + #ifndef MAGNUM_TARGET_WEBGL + , out._perInstanceJointCountUniform, out._perVertexJointCountUniform + #endif #endif ); Containers::Optional geom; diff --git a/src/Magnum/Shaders/MeshVisualizerGL.h b/src/Magnum/Shaders/MeshVisualizerGL.h index ae177f6dd..9b8454172 100644 --- a/src/Magnum/Shaders/MeshVisualizerGL.h +++ b/src/Magnum/Shaders/MeshVisualizerGL.h @@ -84,7 +84,10 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr static MAGNUM_SHADERS_LOCAL void assertExtensions(const FlagsBase flags); static MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs, const FlagsBase flags #ifndef MAGNUM_TARGET_GLES2 - , UnsignedInt dimensions, UnsignedInt jointCount, UnsignedInt perVertexJointCount, UnsignedInt secondaryPerVertexJointCount, UnsignedInt materialCount, UnsignedInt drawCount, UnsignedInt perInstanceJointCountUniform, UnsignedInt perVertexJointCountUniform + , UnsignedInt dimensions, UnsignedInt jointCount, UnsignedInt perVertexJointCount, UnsignedInt secondaryPerVertexJointCount, UnsignedInt materialCount, UnsignedInt drawCount + #ifndef MAGNUM_TARGET_WEBGL + , UnsignedInt perInstanceJointCountUniform, UnsignedInt perVertexJointCountUniform + #endif #endif ); diff --git a/src/Magnum/Shaders/PhongGL.cpp b/src/Magnum/Shaders/PhongGL.cpp index fd79a0a17..083e592b8 100644 --- a/src/Magnum/Shaders/PhongGL.cpp +++ b/src/Magnum/Shaders/PhongGL.cpp @@ -164,7 +164,11 @@ PhongGL::CompileState PhongGL::compile(const Configuration& configuration) { #ifndef MAGNUM_TARGET_GLES const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version version = context.supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif PhongGL out{NoInit}; @@ -224,6 +228,13 @@ PhongGL::CompileState PhongGL::compile(const Configuration& configuration) { .addSource(configuration.flags() >= Flag::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n"_s : ""_s); #ifndef MAGNUM_TARGET_GLES2 if(configuration.perVertexJointCount() || configuration.secondaryPerVertexJointCount()) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION are needed only in the non-UBO case if explicit + uniform location (desktop / ES3.1) is supported, and _INITIALIZER is + desktop-only, so don't even have this branch on WebGL. OTOH, + branching on explicit uniform location support and adding just the + _INITIALIZER if not wouldn't really save much (have to format() + anyway), so passing them always. */ if(!(configuration.flags() >= Flag::UniformBuffers)) { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" @@ -242,7 +253,9 @@ PhongGL::CompileState PhongGL::compile(const Configuration& configuration) { ("mat4(1.0), "_s*configuration.jointCount()).exceptSuffix(2), #endif out._perInstanceJointCountUniform)); - } else { + } else + #endif + { vert.addSource(Utility::format( "#define JOINT_COUNT {}\n" "#define PER_VERTEX_JOINT_COUNT {}u\n" @@ -253,12 +266,23 @@ PhongGL::CompileState PhongGL::compile(const Configuration& configuration) { } } if(configuration.flags() >= Flag::DynamicPerVertexJointCount) { - if(!(configuration.flags() >= Flag::UniformBuffers)) { + #ifndef MAGNUM_TARGET_WEBGL + /* The _LOCATION is needed only if explicit uniform location (desktop / + ES3.1) is supported, a plain string can be added otherwise. This is + an immediate uniform also in the UBO case. */ + #ifndef MAGNUM_TARGET_GLES + if(context.isExtensionSupported(version)) + #else + if(version >= GL::Version::GLES310) + #endif + { vert.addSource(Utility::format( "#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n" "#define PER_VERTEX_JOINT_COUNT_LOCATION {}\n", out._perVertexJointCountUniform)); - } else { + } else + #endif + { vert.addSource("#define DYNAMIC_PER_VERTEX_JOINT_COUNT\n"_s); } } @@ -312,17 +336,29 @@ PhongGL::CompileState PhongGL::compile(const Configuration& configuration) { } else #endif { + /* The _LOCATION are needed only if explicit uniform location (desktop + / ES3.1) is supported, thus not even defining them on ES2 & WebGL. + OTOH, branching on explicit uniform location support and adding just + the first two wouldn't really save much (have to format() anyway), + so passing them otherwise always. */ frag.addSource(Utility::format( "#define LIGHT_COUNT {}\n" "#define PER_DRAW_LIGHT_COUNT {}\n" + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) "#define LIGHT_COLORS_LOCATION {}\n" "#define LIGHT_SPECULAR_COLORS_LOCATION {}\n" - "#define LIGHT_RANGES_LOCATION {}\n", + "#define LIGHT_RANGES_LOCATION {}\n" + #endif + , configuration.lightCount(), - configuration.perDrawLightCount(), + configuration.perDrawLightCount() + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + , out._lightColorsUniform, out._lightSpecularColorsUniform, - out._lightRangesUniform)); + out._lightRangesUniform + #endif + )); } #ifndef MAGNUM_TARGET_GLES if(!(configuration.flags() >= Flag::UniformBuffers) && configuration.lightCount()) diff --git a/src/Magnum/Shaders/PhongGL.h b/src/Magnum/Shaders/PhongGL.h index 46ea56df8..7a88116dc 100644 --- a/src/Magnum/Shaders/PhongGL.h +++ b/src/Magnum/Shaders/PhongGL.h @@ -2333,10 +2333,10 @@ class MAGNUM_SHADERS_EXPORT PhongGL::Configuration { private: Flags _flags; - UnsignedInt _lightCount = 1; + UnsignedInt _lightCount = 1, + _perDrawLightCount = 1; #ifndef MAGNUM_TARGET_GLES2 UnsignedInt - _perDrawLightCount = 1, _jointCount = 0, _perVertexJointCount = 0, _secondaryPerVertexJointCount = 0, diff --git a/src/Magnum/Shaders/VectorGL.cpp b/src/Magnum/Shaders/VectorGL.cpp index 0b228254f..2288e961f 100644 --- a/src/Magnum/Shaders/VectorGL.cpp +++ b/src/Magnum/Shaders/VectorGL.cpp @@ -103,7 +103,11 @@ template typename VectorGL::CompileState Vec #ifndef MAGNUM_TARGET_GLES const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version version = context.supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif GL::Shader vert = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Vertex); diff --git a/src/Magnum/Shaders/VertexColorGL.cpp b/src/Magnum/Shaders/VertexColorGL.cpp index 234298a59..cf51a6935 100644 --- a/src/Magnum/Shaders/VertexColorGL.cpp +++ b/src/Magnum/Shaders/VertexColorGL.cpp @@ -94,7 +94,11 @@ template typename VertexColorGL::CompileStat #ifndef MAGNUM_TARGET_GLES const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version version = context.supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version version = context.supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif GL::Shader vert = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Vertex); diff --git a/src/Magnum/TextureTools/DistanceField.cpp b/src/Magnum/TextureTools/DistanceField.cpp index 6f768eacf..f2e1b56d5 100644 --- a/src/Magnum/TextureTools/DistanceField.cpp +++ b/src/Magnum/TextureTools/DistanceField.cpp @@ -96,7 +96,11 @@ DistanceFieldShader::DistanceFieldShader(const UnsignedInt radius) { #ifndef MAGNUM_TARGET_GLES const GL::Version v = GL::Context::current().supportedVersion({GL::Version::GL320, GL::Version::GL300, GL::Version::GL210}); #else - const GL::Version v = GL::Context::current().supportedVersion({GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200}); + const GL::Version v = GL::Context::current().supportedVersion({ + #ifndef MAGNUM_TARGET_WEBGL + GL::Version::GLES310, + #endif + GL::Version::GLES300, GL::Version::GLES200}); #endif GL::Shader vert = Shaders::Implementation::createCompatibilityShader(rs, v, GL::Shader::Type::Vertex);