1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Implementation of the state classes for mananging GLES 3.1 Vertex Array Objects.
7 //
8
9 #include "libANGLE/VertexAttribute.h"
10
11 namespace gl
12 {
13
14 // [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361
15 // Table 20.2: Vertex Array Object State
VertexBinding()16 VertexBinding::VertexBinding() : mStride(16u), mDivisor(0), mOffset(0)
17 {
18 }
19
VertexBinding(VertexBinding && binding)20 VertexBinding::VertexBinding(VertexBinding &&binding)
21 {
22 *this = std::move(binding);
23 }
24
~VertexBinding()25 VertexBinding::~VertexBinding()
26 {
27 }
28
operator =(VertexBinding && binding)29 VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
30 {
31 if (this != &binding)
32 {
33 mStride = binding.mStride;
34 mDivisor = binding.mDivisor;
35 mOffset = binding.mOffset;
36 std::swap(binding.mBuffer, mBuffer);
37 }
38 return *this;
39 }
40
VertexAttribute(GLuint bindingIndex)41 VertexAttribute::VertexAttribute(GLuint bindingIndex)
42 : enabled(false),
43 type(GL_FLOAT),
44 size(4u),
45 normalized(false),
46 pureInteger(false),
47 pointer(nullptr),
48 relativeOffset(0),
49 vertexAttribArrayStride(0),
50 bindingIndex(bindingIndex)
51 {
52 }
53
VertexAttribute(VertexAttribute && attrib)54 VertexAttribute::VertexAttribute(VertexAttribute &&attrib)
55 : enabled(attrib.enabled),
56 type(attrib.type),
57 size(attrib.size),
58 normalized(attrib.normalized),
59 pureInteger(attrib.pureInteger),
60 pointer(attrib.pointer),
61 relativeOffset(attrib.relativeOffset),
62 vertexAttribArrayStride(attrib.vertexAttribArrayStride),
63 bindingIndex(attrib.bindingIndex)
64 {
65 }
66
operator =(VertexAttribute && attrib)67 VertexAttribute &VertexAttribute::operator=(VertexAttribute &&attrib)
68 {
69 if (this != &attrib)
70 {
71 enabled = attrib.enabled;
72 type = attrib.type;
73 size = attrib.size;
74 normalized = attrib.normalized;
75 pureInteger = attrib.pureInteger;
76 pointer = attrib.pointer;
77 relativeOffset = attrib.relativeOffset;
78 vertexAttribArrayStride = attrib.vertexAttribArrayStride;
79 bindingIndex = attrib.bindingIndex;
80 }
81 return *this;
82 }
83
ComputeVertexAttributeTypeSize(const VertexAttribute & attrib)84 size_t ComputeVertexAttributeTypeSize(const VertexAttribute& attrib)
85 {
86 GLuint size = attrib.size;
87 switch (attrib.type)
88 {
89 case GL_BYTE: return size * sizeof(GLbyte);
90 case GL_UNSIGNED_BYTE: return size * sizeof(GLubyte);
91 case GL_SHORT: return size * sizeof(GLshort);
92 case GL_UNSIGNED_SHORT: return size * sizeof(GLushort);
93 case GL_INT: return size * sizeof(GLint);
94 case GL_UNSIGNED_INT: return size * sizeof(GLuint);
95 case GL_INT_2_10_10_10_REV: return 4;
96 case GL_UNSIGNED_INT_2_10_10_10_REV: return 4;
97 case GL_FIXED: return size * sizeof(GLfixed);
98 case GL_HALF_FLOAT: return size * sizeof(GLhalf);
99 case GL_FLOAT: return size * sizeof(GLfloat);
100 default: UNREACHABLE(); return size * sizeof(GLfloat);
101 }
102 }
103
ComputeVertexAttributeStride(const VertexAttribute & attrib,const VertexBinding & binding)104 size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding)
105 {
106 // In ES 3.1, VertexAttribPointer will store the type size in the binding stride.
107 // Hence, rendering always uses the binding's stride.
108 return attrib.enabled ? binding.getStride() : 16u;
109 }
110
111 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
ComputeVertexAttributeOffset(const VertexAttribute & attrib,const VertexBinding & binding)112 GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding)
113 {
114 return attrib.relativeOffset + binding.getOffset();
115 }
116
ComputeVertexBindingElementCount(GLuint divisor,size_t drawCount,size_t instanceCount)117 size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount)
118 {
119 // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
120 //
121 // A vertex attribute with a positive divisor loads one instanced vertex for every set of
122 // non-instanced vertices, and the instanced vertex index advances once every "mDivisor"
123 // instances.
124 if (instanceCount > 0 && divisor > 0)
125 {
126 // When instanceDrawCount is not a multiple attrib.divisor, the division must round up.
127 // For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced
128 // vertices.
129 return (instanceCount + divisor - 1u) / divisor;
130 }
131
132 return drawCount;
133 }
134
GetVertexAttributeBaseType(const VertexAttribute & attrib)135 GLenum GetVertexAttributeBaseType(const VertexAttribute &attrib)
136 {
137 if (attrib.pureInteger)
138 {
139 switch (attrib.type)
140 {
141 case GL_BYTE:
142 case GL_SHORT:
143 case GL_INT:
144 return GL_INT;
145
146 case GL_UNSIGNED_BYTE:
147 case GL_UNSIGNED_SHORT:
148 case GL_UNSIGNED_INT:
149 return GL_UNSIGNED_INT;
150
151 default:
152 UNREACHABLE();
153 return GL_NONE;
154 }
155 }
156 else
157 {
158 return GL_FLOAT;
159 }
160 }
161
162 } // namespace gl
163