diff options
Diffstat (limited to 'src/mbgl/gfx/attribute.hpp')
-rw-r--r-- | src/mbgl/gfx/attribute.hpp | 123 |
1 files changed, 94 insertions, 29 deletions
diff --git a/src/mbgl/gfx/attribute.hpp b/src/mbgl/gfx/attribute.hpp index 0dce6b2a06..4f44d68d7b 100644 --- a/src/mbgl/gfx/attribute.hpp +++ b/src/mbgl/gfx/attribute.hpp @@ -1,8 +1,11 @@ #pragma once #include <mbgl/gfx/types.hpp> +#include <mbgl/gfx/vertex_buffer.hpp> #include <mbgl/util/type_list.hpp> #include <mbgl/util/indexed_tuple.hpp> +#include <mbgl/util/ignore.hpp> +#include <mbgl/util/optional.hpp> #include <array> #include <type_traits> @@ -79,6 +82,21 @@ struct VertexDescriptor { AttributeDescriptor attributes[5]; }; +class AttributeBinding { +public: + AttributeDescriptor attribute; + uint8_t vertexStride; + const VertexBufferResource* vertexBufferResource; + uint32_t vertexOffset; + + friend bool operator==(const AttributeBinding& lhs, const AttributeBinding& rhs) { + return lhs.attribute == rhs.attribute && + lhs.vertexStride == rhs.vertexStride && + lhs.vertexBufferResource == rhs.vertexBufferResource && + lhs.vertexOffset == rhs.vertexOffset; + } +}; + // 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 @@ -89,32 +107,32 @@ struct VertexDescriptor { namespace detail { template <class...> -struct Vertex; +struct VertexType; template <class A1> -struct Vertex<A1> { - using Type = Vertex<A1>; +struct VertexType<A1> { + using Type = VertexType<A1>; typename A1::Value a1; } MBGL_VERTEX_ALIGN; template <class A1, class A2> -struct Vertex<A1, A2> { - using Type = Vertex<A1, A2>; +struct VertexType<A1, A2> { + using Type = VertexType<A1, A2>; typename A1::Value a1; typename A2::Value a2; } MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3> -struct Vertex<A1, A2, A3> { - using Type = Vertex<A1, A2, A3>; +struct VertexType<A1, A2, A3> { + using Type = VertexType<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> -struct Vertex<A1, A2, A3, A4> { - using Type = Vertex<A1, A2, A3, A4>; +struct VertexType<A1, A2, A3, A4> { + using Type = VertexType<A1, A2, A3, A4>; typename A1::Value a1; typename A2::Value a2; typename A3::Value a3; @@ -122,8 +140,8 @@ struct Vertex<A1, A2, A3, A4> { } MBGL_VERTEX_ALIGN; template <class A1, class A2, class A3, class A4, class A5> -struct Vertex<A1, A2, A3, A4, A5> { - using Type = Vertex<A1, A2, A3, A4, A5>; +struct VertexType<A1, A2, A3, A4, A5> { + using Type = VertexType<A1, A2, A3, A4, A5>; typename A1::Value a1; typename A2::Value a2; typename A3::Value a3; @@ -135,8 +153,8 @@ template <class> struct Descriptor; template <class A1> -struct Descriptor<Vertex<A1>> { - using Type = Vertex<A1>; +struct Descriptor<VertexType<A1>> { + using Type = VertexType<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, { @@ -145,11 +163,11 @@ struct Descriptor<Vertex<A1>> { }; template <class A1> -constexpr const VertexDescriptor Descriptor<Vertex<A1>>::data; +constexpr const VertexDescriptor Descriptor<VertexType<A1>>::data; template <class A1, class A2> -struct Descriptor<Vertex<A1, A2>> { - using Type = Vertex<A1, A2>; +struct Descriptor<VertexType<A1, A2>> { + using Type = VertexType<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, { @@ -159,11 +177,11 @@ struct Descriptor<Vertex<A1, A2>> { }; template <class A1, class A2> -constexpr const VertexDescriptor Descriptor<Vertex<A1, A2>>::data; +constexpr const VertexDescriptor Descriptor<VertexType<A1, A2>>::data; template <class A1, class A2, class A3> -struct Descriptor<Vertex<A1, A2, A3>> { - using Type = Vertex<A1, A2, A3>; +struct Descriptor<VertexType<A1, A2, A3>> { + using Type = VertexType<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, { @@ -174,11 +192,11 @@ struct Descriptor<Vertex<A1, A2, A3>> { }; template <class A1, class A2, class A3> -constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3>>::data; +constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3>>::data; template <class A1, class A2, class A3, class A4> -struct Descriptor<Vertex<A1, A2, A3, A4>> { - using Type = Vertex<A1, A2, A3, A4>; +struct Descriptor<VertexType<A1, A2, A3, A4>> { + using Type = VertexType<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, { @@ -190,11 +208,11 @@ struct Descriptor<Vertex<A1, A2, A3, A4>> { }; template <class A1, class A2, class A3, class A4> -constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4>>::data; +constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3, A4>>::data; template <class A1, class A2, class A3, class A4, class A5> -struct Descriptor<Vertex<A1, A2, A3, A4, A5>> { - using Type = Vertex<A1, A2, A3, A4, A5>; +struct Descriptor<VertexType<A1, A2, A3, A4, A5>> { + using Type = VertexType<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, { @@ -207,11 +225,14 @@ struct Descriptor<Vertex<A1, A2, A3, A4, A5>> { }; template <class A1, class A2, class A3, class A4, class A5> -constexpr const VertexDescriptor Descriptor<Vertex<A1, A2, A3, A4, A5>>::data; +constexpr const VertexDescriptor Descriptor<VertexType<A1, A2, A3, A4, A5>>::data; + +template <class> +struct Vertex; template <class... As> struct Vertex<TypeList<As...>> { - using Type = Vertex<typename As::Type...>; + using Type = VertexType<typename As::Type...>; }; } // namespace detail @@ -219,8 +240,52 @@ struct Vertex<TypeList<As...>> { template <class A> using Vertex = typename detail::Vertex<A>::Type; -template <class V> -using VertexDescriptorOf = detail::Descriptor<V>; +template <class T> +using VertexType = typename detail::VertexType<T>; + +template <size_t I = 0, class... As> +AttributeBinding attributeBinding(const VertexBuffer<detail::VertexType<As...>>& buffer) { + using Descriptor = detail::Descriptor<detail::VertexType<As...>>; + static_assert(I < Descriptor::data.count, "attribute index must be in range"); + return { + Descriptor::data.attributes[I], + Descriptor::data.stride, + buffer.resource.get(), + 0, + }; +} + +optional<gfx::AttributeBinding> offsetAttributeBinding(const optional<gfx::AttributeBinding>& binding, std::size_t vertexOffset); + +template <class> +class AttributeBindings; + +template <class... As> +class AttributeBindings<TypeList<As...>> final + : public IndexedTuple<TypeList<As...>, + TypeList<ExpandToType<As, optional<AttributeBinding>>...>> { + using Base = IndexedTuple<TypeList<As...>, + TypeList<ExpandToType<As, optional<AttributeBinding>>...>>; + +public: + AttributeBindings(const VertexBuffer<Vertex<TypeList<As...>>>& buffer) + : Base{ attributeBinding<TypeIndex<As, As...>::value>(buffer)... } { + } + + template <class... Args> + AttributeBindings(Args&&... args) : Base(std::forward<Args>(args)...) { + } + + AttributeBindings offset(const std::size_t vertexOffset) const { + return { offsetAttributeBinding(Base::template get<As>(), vertexOffset)... }; + } + + uint32_t activeCount() const { + uint32_t result = 0; + util::ignore({ ((result += bool(Base::template get<As>())), 0)... }); + return result; + } +}; } // namespace gfx } // namespace mbgl |