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