diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-06-12 18:16:51 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2017-06-13 19:21:46 +0200 |
commit | 7f8f75b1c9d50fe02d0112717de5b4a79e1e44ce (patch) | |
tree | 7c68af71d5e6aa5c6628b94e6d2b039184b1df7d /src | |
parent | 9a05ebac5202b6e4b59f43707b96b4acd4c00b7b (diff) | |
download | qtlocation-mapboxgl-7f8f75b1c9d50fe02d0112717de5b4a79e1e44ce.tar.gz |
[core] verify that the active uniform types match our assumed types
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/gl/types.hpp | 20 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.cpp | 93 | ||||
-rw-r--r-- | src/mbgl/gl/uniform.hpp | 31 |
3 files changed, 144 insertions, 0 deletions
diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp index 31e3076f67..74ce67fba6 100644 --- a/src/mbgl/gl/types.hpp +++ b/src/mbgl/gl/types.hpp @@ -76,5 +76,25 @@ constexpr bool operator!=(const PixelStorageType& a, const PixelStorageType& b) using BinaryProgramFormat = uint32_t; +enum class UniformDataType : uint32_t { + Float = 0x1406, + FloatVec2 = 0x8B50, + FloatVec3 = 0x8B51, + FloatVec4 = 0x8B52, + Int = 0x1404, + IntVec2 = 0x8B53, + IntVec3 = 0x8B54, + IntVec4 = 0x8B55, + Bool = 0x8B56, + BoolVec2 = 0x8B57, + BoolVec3 = 0x8B58, + BoolVec4 = 0x8B59, + FloatMat2 = 0x8B5A, + FloatMat3 = 0x8B5B, + FloatMat4 = 0x8B5C, + Sampler2D = 0x8B5E, + SamplerCube = 0x8B60, +}; + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/uniform.cpp b/src/mbgl/gl/uniform.cpp index 7b674f2cde..2946980c19 100644 --- a/src/mbgl/gl/uniform.cpp +++ b/src/mbgl/gl/uniform.cpp @@ -4,6 +4,8 @@ #include <mbgl/util/size.hpp> #include <mbgl/util/convert.hpp> +#include <memory> + namespace mbgl { namespace gl { @@ -79,5 +81,96 @@ void bindUniform<std::array<uint16_t, 2>>(UniformLocation location, const std::a // Add more as needed. +#ifndef NDEBUG + +ActiveUniforms activeUniforms(ProgramID id) { + ActiveUniforms active; + + GLint count; + GLint maxLength; + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &count)); + MBGL_CHECK_ERROR(glGetProgramiv(id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength)); + + auto name = std::make_unique<GLchar[]>(maxLength); + GLsizei length; + GLint size; + GLenum type; + for (GLint index = 0; index < count; index++) { + MBGL_CHECK_ERROR( + glGetActiveUniform(id, index, maxLength, &length, &size, &type, name.get())); + active.emplace( + std::string{ name.get(), static_cast<size_t>(length) }, + ActiveUniform{ static_cast<size_t>(size), static_cast<UniformDataType>(type) }); + } + + return active; +} + +template <> +bool verifyUniform<float>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::Float); + return true; +} + +template <> +bool verifyUniform<std::array<float, 2>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatVec2); + return true; +} + +template <> +bool verifyUniform<std::array<float, 3>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatVec3); + return true; +} + +template <> +bool verifyUniform<std::array<double, 16>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatMat4); + return true; +} + +template <> +bool verifyUniform<bool>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && + (uniform.type == UniformDataType::Bool || + uniform.type == UniformDataType::Int || + uniform.type == UniformDataType::Float)); + return true; +} + +template <> +bool verifyUniform<uint8_t>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && + (uniform.type == UniformDataType::Int || + uniform.type == UniformDataType::Float || + uniform.type == UniformDataType::Sampler2D)); + return true; +} + +template <> +bool verifyUniform<Color>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatVec4); + return true; +} + +template <> +bool verifyUniform<Size>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && uniform.type == UniformDataType::FloatVec2); + return true; +} + +template <> +bool verifyUniform<std::array<uint16_t, 2>>(const ActiveUniform& uniform) { + assert(uniform.size == 1 && + (uniform.type == UniformDataType::IntVec2 || + uniform.type == UniformDataType::FloatVec2)); + return true; +} + +// Add more as needed. + +#endif + } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/uniform.hpp b/src/mbgl/gl/uniform.hpp index 34a32aeee9..b877f10e46 100644 --- a/src/mbgl/gl/uniform.hpp +++ b/src/mbgl/gl/uniform.hpp @@ -7,6 +7,7 @@ #include <array> #include <vector> +#include <map> #include <functional> namespace mbgl { @@ -22,11 +23,29 @@ public: T t; }; +class ActiveUniform { +public: + std::size_t size; + UniformDataType type; +}; + +#ifndef NDEBUG + +template <class T> +bool verifyUniform(const ActiveUniform&); + +using ActiveUniforms = std::map<std::string, ActiveUniform>; +ActiveUniforms activeUniforms(ProgramID); + +#endif + template <class Tag, class T> class Uniform { public: using Value = UniformValue<Tag, T>; + using Type = T; + class State { public: void operator=(const Value& value) { @@ -70,6 +89,18 @@ public: using NamedLocations = std::vector<std::pair<const std::string, UniformLocation>>; static State bindLocations(const ProgramID& id) { +#ifndef NDEBUG + // Verify active uniform types match the enum + const auto active = activeUniforms(id); + + util::ignore( + { // Some shader programs have uniforms declared, but not used, so they're not active. + // Therefore, we'll only verify them when they are indeed active. + (active.find(Us::name()) != active.end() + ? verifyUniform<typename Us::Type>(active.at(Us::name())) + : false)... }); +#endif + return State { { uniformLocation(id, Us::name()) }... }; } |