diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2019-03-04 13:09:51 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2019-03-06 16:12:51 +0100 |
commit | 2f646af255bf05bd50070deb83bb89e48509afc4 (patch) | |
tree | 59c4baf0f1e560845bb49de09a36a67c0fdfc491 /src/mbgl/gfx | |
parent | d5816b6db265b36cf1360dc684725b0f7427d959 (diff) | |
download | qtlocation-mapboxgl-2f646af255bf05bd50070deb83bb89e48509afc4.tar.gz |
[core] make vertex descriptors constexpr
Diffstat (limited to 'src/mbgl/gfx')
-rw-r--r-- | src/mbgl/gfx/attribute.hpp | 232 | ||||
-rw-r--r-- | src/mbgl/gfx/types.hpp | 39 |
2 files changed, 194 insertions, 77 deletions
diff --git a/src/mbgl/gfx/attribute.hpp b/src/mbgl/gfx/attribute.hpp index 66bbf1ec5e..0dce6b2a06 100644 --- a/src/mbgl/gfx/attribute.hpp +++ b/src/mbgl/gfx/attribute.hpp @@ -1,9 +1,11 @@ #pragma once +#include <mbgl/gfx/types.hpp> #include <mbgl/util/type_list.hpp> #include <mbgl/util/indexed_tuple.hpp> #include <array> +#include <type_traits> #include <cstddef> #define MBGL_DEFINE_ATTRIBUTE(type_, n_, name_) \ @@ -14,17 +16,69 @@ } \ } +#define MBGL_VERTEX_ALIGN __attribute__((aligned(4))) + namespace mbgl { namespace gfx { +namespace { + +template <typename, std::size_t> struct AttributeDataTypeOf; +template <> struct AttributeDataTypeOf<int8_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Byte> {}; +template <> struct AttributeDataTypeOf<int8_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Byte2> {}; +template <> struct AttributeDataTypeOf<int8_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Byte3> {}; +template <> struct AttributeDataTypeOf<int8_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Byte4> {}; +template <> struct AttributeDataTypeOf<uint8_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UByte> {}; +template <> struct AttributeDataTypeOf<uint8_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UByte2> {}; +template <> struct AttributeDataTypeOf<uint8_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UByte3> {}; +template <> struct AttributeDataTypeOf<uint8_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UByte4> {}; +template <> struct AttributeDataTypeOf<int16_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Short> {}; +template <> struct AttributeDataTypeOf<int16_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Short2> {}; +template <> struct AttributeDataTypeOf<int16_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Short3> {}; +template <> struct AttributeDataTypeOf<int16_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Short4> {}; +template <> struct AttributeDataTypeOf<uint16_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UShort> {}; +template <> struct AttributeDataTypeOf<uint16_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UShort2> {}; +template <> struct AttributeDataTypeOf<uint16_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UShort3> {}; +template <> struct AttributeDataTypeOf<uint16_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UShort4> {}; +template <> struct AttributeDataTypeOf<int32_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Int> {}; +template <> struct AttributeDataTypeOf<int32_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Int2> {}; +template <> struct AttributeDataTypeOf<int32_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Int3> {}; +template <> struct AttributeDataTypeOf<int32_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Int4> {}; +template <> struct AttributeDataTypeOf<uint32_t, 1> : std::integral_constant<AttributeDataType, AttributeDataType::UInt> {}; +template <> struct AttributeDataTypeOf<uint32_t, 2> : std::integral_constant<AttributeDataType, AttributeDataType::UInt2> {}; +template <> struct AttributeDataTypeOf<uint32_t, 3> : std::integral_constant<AttributeDataType, AttributeDataType::UInt3> {}; +template <> struct AttributeDataTypeOf<uint32_t, 4> : std::integral_constant<AttributeDataType, AttributeDataType::UInt4> {}; +template <> struct AttributeDataTypeOf<float, 1> : std::integral_constant<AttributeDataType, AttributeDataType::Float> {}; +template <> struct AttributeDataTypeOf<float, 2> : std::integral_constant<AttributeDataType, AttributeDataType::Float2> {}; +template <> struct AttributeDataTypeOf<float, 3> : std::integral_constant<AttributeDataType, AttributeDataType::Float3> {}; +template <> struct AttributeDataTypeOf<float, 4> : std::integral_constant<AttributeDataType, AttributeDataType::Float4> {}; + +} // namespace + template <typename T, std::size_t N> class AttributeType { public: - using ValueType = T; + using ElementType = T; + static constexpr AttributeDataType DataType = AttributeDataTypeOf<T, N>::value; static constexpr size_t Dimensions = N; using Value = std::array<T, N>; }; +struct AttributeDescriptor { + AttributeDataType dataType; + uint8_t offset; +}; + +inline bool operator==(const AttributeDescriptor& lhs, const AttributeDescriptor& rhs) { + return lhs.dataType == rhs.dataType && lhs.offset == rhs.offset; +} + +struct VertexDescriptor { + uint8_t stride; + uint8_t count; + AttributeDescriptor attributes[5]; +}; + // Attribute binding requires member offsets. The only standard way to // obtain an offset is the offsetof macro. The offsetof macro has defined // behavior only for standard layout types. That rules out std::tuple and @@ -35,114 +89,138 @@ public: namespace detail { template <class...> -class Vertex; - -template <> -class Vertex<> { -public: - using VertexType = Vertex<>; -}; +struct Vertex; template <class A1> -class Vertex<A1> { -public: - A1 a1; - - using VertexType = Vertex<A1>; - static const std::size_t attributeOffsets[1]; -}; +struct Vertex<A1> { + using Type = Vertex<A1>; + typename A1::Value a1; +} MBGL_VERTEX_ALIGN; template <class A1, class A2> -class Vertex<A1, A2> { -public: - A1 a1; - A2 a2; - - using VertexType = Vertex<A1, A2>; - static const std::size_t attributeOffsets[2]; -}; +struct Vertex<A1, A2> { + using Type = Vertex<A1, A2>; + typename A1::Value a1; + typename A2::Value a2; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3> -class Vertex<A1, A2, A3> { -public: - A1 a1; - A2 a2; - A3 a3; - - using VertexType = Vertex<A1, A2, A3>; - static const std::size_t attributeOffsets[3]; -}; +struct Vertex<A1, A2, A3> { + using Type = Vertex<A1, A2, A3>; + typename A1::Value a1; + typename A2::Value a2; + typename A3::Value a3; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3, class A4> -class Vertex<A1, A2, A3, A4> { -public: - A1 a1; - A2 a2; - A3 a3; - A4 a4; - - using VertexType = Vertex<A1, A2, A3, A4>; - static const std::size_t attributeOffsets[4]; -}; +struct Vertex<A1, A2, A3, A4> { + using Type = Vertex<A1, A2, A3, A4>; + typename A1::Value a1; + typename A2::Value a2; + typename A3::Value a3; + typename A4::Value a4; +} MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3, class A4, class A5> -class Vertex<A1, A2, A3, A4, A5> { -public: - A1 a1; - A2 a2; - A3 a3; - A4 a4; - A5 a5; - - using VertexType = Vertex<A1, A2, A3, A4, A5>; - static const std::size_t attributeOffsets[5]; -}; +struct Vertex<A1, A2, A3, A4, A5> { + using Type = Vertex<A1, A2, A3, A4, A5>; + typename A1::Value a1; + typename A2::Value a2; + typename A3::Value a3; + typename A4::Value a4; + typename A5::Value a5; +} MBGL_VERTEX_ALIGN; + +template <class> +struct Descriptor; template <class A1> -const std::size_t Vertex<A1>::attributeOffsets[1] = { - offsetof(VertexType, a1) +struct Descriptor<Vertex<A1>> { + using Type = Vertex<A1>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor data = { sizeof(Type), 1, { + { A1::DataType, offsetof(Type, a1) }, + }}; }; +template <class A1> +constexpr const VertexDescriptor Descriptor<Vertex<A1>>::data; + template <class A1, class A2> -const std::size_t Vertex<A1, A2>::attributeOffsets[2] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2) +struct Descriptor<Vertex<A1, A2>> { + using Type = Vertex<A1, A2>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor data = { sizeof(Type), 2, { + { A1::DataType, offsetof(Type, a1) }, + { A2::DataType, offsetof(Type, a2) }, + }}; }; +template <class A1, class A2> +constexpr const VertexDescriptor Descriptor<Vertex<A1, A2>>::data; + template <class A1, class A2, class A3> -const std::size_t Vertex<A1, A2, A3>::attributeOffsets[3] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3) +struct Descriptor<Vertex<A1, A2, A3>> { + using Type = Vertex<A1, A2, A3>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor data = { sizeof(Type), 3, { + { A1::DataType, offsetof(Type, a1) }, + { A2::DataType, offsetof(Type, a2) }, + { A3::DataType, offsetof(Type, a3) }, + }}; }; +template <class A1, class A2, class A3> +constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3>>::data; + template <class A1, class A2, class A3, class A4> -const std::size_t Vertex<A1, A2, A3, A4>::attributeOffsets[4] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3), - offsetof(VertexType, a4) +struct Descriptor<Vertex<A1, A2, A3, A4>> { + using Type = Vertex<A1, A2, A3, A4>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor data = { sizeof(Type), 4, { + { A1::DataType, offsetof(Type, a1) }, + { A2::DataType, offsetof(Type, a2) }, + { A3::DataType, offsetof(Type, a3) }, + { A4::DataType, offsetof(Type, a4) }, + }}; }; +template <class A1, class A2, class A3, class A4> +constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4>>::data; + template <class A1, class A2, class A3, class A4, class A5> -const std::size_t Vertex<A1, A2, A3, A4, A5>::attributeOffsets[5] = { - offsetof(VertexType, a1), - offsetof(VertexType, a2), - offsetof(VertexType, a3), - offsetof(VertexType, a4), - offsetof(VertexType, a5) +struct Descriptor<Vertex<A1, A2, A3, A4, A5>> { + using Type = Vertex<A1, A2, A3, A4, A5>; + static_assert(sizeof(Type) < 256, "vertex type must be smaller than 256 bytes"); + static_assert(std::is_standard_layout<Type>::value, "vertex type must use standard layout"); + static constexpr const VertexDescriptor data = { sizeof(Type), 5, { + { A1::DataType, offsetof(Type, a1) }, + { A2::DataType, offsetof(Type, a2) }, + { A3::DataType, offsetof(Type, a3) }, + { A4::DataType, offsetof(Type, a4) }, + { A5::DataType, offsetof(Type, a5) }, + }}; }; +template <class A1, class A2, class A3, class A4, class A5> +constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4, A5>>::data; + template <class... As> -class Vertex<TypeList<As...>> { -public: - using VertexType = Vertex<typename As::Type::Value...>; +struct Vertex<TypeList<As...>> { + using Type = Vertex<typename As::Type...>; }; } // namespace detail template <class A> -using Vertex = typename detail::Vertex<A>::VertexType; +using Vertex = typename detail::Vertex<A>::Type; + +template <class V> +using VertexDescriptorOf = detail::Descriptor<V>; } // namespace gfx } // namespace mbgl diff --git a/src/mbgl/gfx/types.hpp b/src/mbgl/gfx/types.hpp index d1421dddb7..a9cb4e1ece 100644 --- a/src/mbgl/gfx/types.hpp +++ b/src/mbgl/gfx/types.hpp @@ -15,6 +15,45 @@ enum class PrimitiveType : uint8_t { TriangleFan, }; +enum class AttributeDataType : uint8_t { + Byte, + Byte2, + Byte3, + Byte4, + + UByte, + UByte2, + UByte3, + UByte4, + + Short, + Short2, + Short3, + Short4, + + UShort, + UShort2, + UShort3, + UShort4, + + Int, + Int2, + Int3, + Int4, + + UInt, + UInt2, + UInt3, + UInt4, + + Float, + Float2, + Float3, + Float4, + + Invalid = 255, +}; + enum class ColorBlendEquationType : uint8_t { Add, Subtract, |