1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL Utilities
3*35238bceSAndroid Build Coastguard Worker * ---------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker *
7*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker *
11*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker *
13*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker *
19*35238bceSAndroid Build Coastguard Worker *//*!
20*35238bceSAndroid Build Coastguard Worker * \file
21*35238bceSAndroid Build Coastguard Worker * \brief Draw call utilities.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deInt32.h"
30*35238bceSAndroid Build Coastguard Worker #include "deMemory.h"
31*35238bceSAndroid Build Coastguard Worker
32*35238bceSAndroid Build Coastguard Worker #include <vector>
33*35238bceSAndroid Build Coastguard Worker #include <set>
34*35238bceSAndroid Build Coastguard Worker #include <iterator>
35*35238bceSAndroid Build Coastguard Worker
36*35238bceSAndroid Build Coastguard Worker namespace glu
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker namespace
39*35238bceSAndroid Build Coastguard Worker {
40*35238bceSAndroid Build Coastguard Worker
41*35238bceSAndroid Build Coastguard Worker struct VertexAttributeDescriptor
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker int location;
44*35238bceSAndroid Build Coastguard Worker VertexComponentType componentType;
45*35238bceSAndroid Build Coastguard Worker VertexComponentConversion convert;
46*35238bceSAndroid Build Coastguard Worker int numComponents;
47*35238bceSAndroid Build Coastguard Worker int numElements;
48*35238bceSAndroid Build Coastguard Worker int stride; //!< Stride or 0 if using default stride.
49*35238bceSAndroid Build Coastguard Worker const void *pointer; //!< Pointer or offset.
50*35238bceSAndroid Build Coastguard Worker
VertexAttributeDescriptorglu::__anonf067fd160111::VertexAttributeDescriptor51*35238bceSAndroid Build Coastguard Worker VertexAttributeDescriptor(int location_, VertexComponentType componentType_, VertexComponentConversion convert_,
52*35238bceSAndroid Build Coastguard Worker int numComponents_, int numElements_, int stride_, const void *pointer_)
53*35238bceSAndroid Build Coastguard Worker : location(location_)
54*35238bceSAndroid Build Coastguard Worker , componentType(componentType_)
55*35238bceSAndroid Build Coastguard Worker , convert(convert_)
56*35238bceSAndroid Build Coastguard Worker , numComponents(numComponents_)
57*35238bceSAndroid Build Coastguard Worker , numElements(numElements_)
58*35238bceSAndroid Build Coastguard Worker , stride(stride_)
59*35238bceSAndroid Build Coastguard Worker , pointer(pointer_)
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker }
62*35238bceSAndroid Build Coastguard Worker
VertexAttributeDescriptorglu::__anonf067fd160111::VertexAttributeDescriptor63*35238bceSAndroid Build Coastguard Worker VertexAttributeDescriptor(void)
64*35238bceSAndroid Build Coastguard Worker : location(0)
65*35238bceSAndroid Build Coastguard Worker , componentType(VTX_COMP_TYPE_LAST)
66*35238bceSAndroid Build Coastguard Worker , convert(VTX_COMP_CONVERT_LAST)
67*35238bceSAndroid Build Coastguard Worker , numComponents(0)
68*35238bceSAndroid Build Coastguard Worker , numElements(0)
69*35238bceSAndroid Build Coastguard Worker , stride(0)
70*35238bceSAndroid Build Coastguard Worker , pointer(0)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker }
73*35238bceSAndroid Build Coastguard Worker };
74*35238bceSAndroid Build Coastguard Worker
75*35238bceSAndroid Build Coastguard Worker struct VertexBufferLayout
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker int size;
78*35238bceSAndroid Build Coastguard Worker std::vector<VertexAttributeDescriptor> attributes;
79*35238bceSAndroid Build Coastguard Worker
VertexBufferLayoutglu::__anonf067fd160111::VertexBufferLayout80*35238bceSAndroid Build Coastguard Worker VertexBufferLayout(int size_ = 0) : size(size_)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker }
83*35238bceSAndroid Build Coastguard Worker };
84*35238bceSAndroid Build Coastguard Worker
85*35238bceSAndroid Build Coastguard Worker struct VertexBufferDescriptor
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker uint32_t buffer;
88*35238bceSAndroid Build Coastguard Worker std::vector<VertexAttributeDescriptor> attributes;
89*35238bceSAndroid Build Coastguard Worker
VertexBufferDescriptorglu::__anonf067fd160111::VertexBufferDescriptor90*35238bceSAndroid Build Coastguard Worker VertexBufferDescriptor(uint32_t buffer_ = 0) : buffer(buffer_)
91*35238bceSAndroid Build Coastguard Worker {
92*35238bceSAndroid Build Coastguard Worker }
93*35238bceSAndroid Build Coastguard Worker };
94*35238bceSAndroid Build Coastguard Worker
95*35238bceSAndroid Build Coastguard Worker class VertexBuffer : public Buffer
96*35238bceSAndroid Build Coastguard Worker {
97*35238bceSAndroid Build Coastguard Worker public:
98*35238bceSAndroid Build Coastguard Worker enum Type
99*35238bceSAndroid Build Coastguard Worker {
100*35238bceSAndroid Build Coastguard Worker TYPE_PLANAR = 0, //!< Data for each vertex array resides in a separate contiguous block in buffer.
101*35238bceSAndroid Build Coastguard Worker TYPE_STRIDED, //!< Vertex arrays are interleaved.
102*35238bceSAndroid Build Coastguard Worker
103*35238bceSAndroid Build Coastguard Worker TYPE_LAST
104*35238bceSAndroid Build Coastguard Worker };
105*35238bceSAndroid Build Coastguard Worker
106*35238bceSAndroid Build Coastguard Worker VertexBuffer(const RenderContext &context, int numBindings, const VertexArrayBinding *bindings,
107*35238bceSAndroid Build Coastguard Worker Type type = TYPE_PLANAR);
108*35238bceSAndroid Build Coastguard Worker ~VertexBuffer(void);
109*35238bceSAndroid Build Coastguard Worker
getDescriptor(void) const110*35238bceSAndroid Build Coastguard Worker const VertexBufferDescriptor &getDescriptor(void) const
111*35238bceSAndroid Build Coastguard Worker {
112*35238bceSAndroid Build Coastguard Worker return m_layout;
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker
115*35238bceSAndroid Build Coastguard Worker private:
116*35238bceSAndroid Build Coastguard Worker VertexBuffer(const VertexBuffer &other);
117*35238bceSAndroid Build Coastguard Worker VertexBuffer &operator=(const VertexBuffer &other);
118*35238bceSAndroid Build Coastguard Worker
119*35238bceSAndroid Build Coastguard Worker VertexBufferDescriptor m_layout;
120*35238bceSAndroid Build Coastguard Worker };
121*35238bceSAndroid Build Coastguard Worker
122*35238bceSAndroid Build Coastguard Worker class IndexBuffer : public Buffer
123*35238bceSAndroid Build Coastguard Worker {
124*35238bceSAndroid Build Coastguard Worker public:
125*35238bceSAndroid Build Coastguard Worker IndexBuffer(const RenderContext &context, IndexType indexType, int numIndices, const void *indices);
126*35238bceSAndroid Build Coastguard Worker ~IndexBuffer(void);
127*35238bceSAndroid Build Coastguard Worker
128*35238bceSAndroid Build Coastguard Worker private:
129*35238bceSAndroid Build Coastguard Worker IndexBuffer(const IndexBuffer &other);
130*35238bceSAndroid Build Coastguard Worker IndexBuffer &operator=(const IndexBuffer &other);
131*35238bceSAndroid Build Coastguard Worker };
132*35238bceSAndroid Build Coastguard Worker
getVtxCompGLType(VertexComponentType type)133*35238bceSAndroid Build Coastguard Worker static uint32_t getVtxCompGLType(VertexComponentType type)
134*35238bceSAndroid Build Coastguard Worker {
135*35238bceSAndroid Build Coastguard Worker switch (type)
136*35238bceSAndroid Build Coastguard Worker {
137*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT8:
138*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_BYTE;
139*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT16:
140*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_SHORT;
141*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT32:
142*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_INT;
143*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT8:
144*35238bceSAndroid Build Coastguard Worker return GL_BYTE;
145*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT16:
146*35238bceSAndroid Build Coastguard Worker return GL_SHORT;
147*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT32:
148*35238bceSAndroid Build Coastguard Worker return GL_INT;
149*35238bceSAndroid Build Coastguard Worker case VTX_COMP_FIXED:
150*35238bceSAndroid Build Coastguard Worker return GL_FIXED;
151*35238bceSAndroid Build Coastguard Worker case VTX_COMP_HALF_FLOAT:
152*35238bceSAndroid Build Coastguard Worker return GL_HALF_FLOAT;
153*35238bceSAndroid Build Coastguard Worker case VTX_COMP_FLOAT:
154*35238bceSAndroid Build Coastguard Worker return GL_FLOAT;
155*35238bceSAndroid Build Coastguard Worker default:
156*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
157*35238bceSAndroid Build Coastguard Worker return GL_NONE;
158*35238bceSAndroid Build Coastguard Worker }
159*35238bceSAndroid Build Coastguard Worker }
160*35238bceSAndroid Build Coastguard Worker
getVtxCompSize(VertexComponentType type)161*35238bceSAndroid Build Coastguard Worker static int getVtxCompSize(VertexComponentType type)
162*35238bceSAndroid Build Coastguard Worker {
163*35238bceSAndroid Build Coastguard Worker switch (type)
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT8:
166*35238bceSAndroid Build Coastguard Worker return 1;
167*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT16:
168*35238bceSAndroid Build Coastguard Worker return 2;
169*35238bceSAndroid Build Coastguard Worker case VTX_COMP_UNSIGNED_INT32:
170*35238bceSAndroid Build Coastguard Worker return 4;
171*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT8:
172*35238bceSAndroid Build Coastguard Worker return 1;
173*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT16:
174*35238bceSAndroid Build Coastguard Worker return 2;
175*35238bceSAndroid Build Coastguard Worker case VTX_COMP_SIGNED_INT32:
176*35238bceSAndroid Build Coastguard Worker return 4;
177*35238bceSAndroid Build Coastguard Worker case VTX_COMP_FIXED:
178*35238bceSAndroid Build Coastguard Worker return 4;
179*35238bceSAndroid Build Coastguard Worker case VTX_COMP_HALF_FLOAT:
180*35238bceSAndroid Build Coastguard Worker return 2;
181*35238bceSAndroid Build Coastguard Worker case VTX_COMP_FLOAT:
182*35238bceSAndroid Build Coastguard Worker return 4;
183*35238bceSAndroid Build Coastguard Worker default:
184*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
185*35238bceSAndroid Build Coastguard Worker return 0;
186*35238bceSAndroid Build Coastguard Worker }
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker
getIndexGLType(IndexType type)189*35238bceSAndroid Build Coastguard Worker static uint32_t getIndexGLType(IndexType type)
190*35238bceSAndroid Build Coastguard Worker {
191*35238bceSAndroid Build Coastguard Worker switch (type)
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT8:
194*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_BYTE;
195*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT16:
196*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_SHORT;
197*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT32:
198*35238bceSAndroid Build Coastguard Worker return GL_UNSIGNED_INT;
199*35238bceSAndroid Build Coastguard Worker default:
200*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
201*35238bceSAndroid Build Coastguard Worker return 0;
202*35238bceSAndroid Build Coastguard Worker }
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker
getIndexSize(IndexType type)205*35238bceSAndroid Build Coastguard Worker static int getIndexSize(IndexType type)
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker switch (type)
208*35238bceSAndroid Build Coastguard Worker {
209*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT8:
210*35238bceSAndroid Build Coastguard Worker return 1;
211*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT16:
212*35238bceSAndroid Build Coastguard Worker return 2;
213*35238bceSAndroid Build Coastguard Worker case INDEXTYPE_UINT32:
214*35238bceSAndroid Build Coastguard Worker return 4;
215*35238bceSAndroid Build Coastguard Worker default:
216*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
217*35238bceSAndroid Build Coastguard Worker return 0;
218*35238bceSAndroid Build Coastguard Worker }
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker
getPrimitiveGLType(PrimitiveType type)221*35238bceSAndroid Build Coastguard Worker static uint32_t getPrimitiveGLType(PrimitiveType type)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker switch (type)
224*35238bceSAndroid Build Coastguard Worker {
225*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_TRIANGLES:
226*35238bceSAndroid Build Coastguard Worker return GL_TRIANGLES;
227*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_TRIANGLE_STRIP:
228*35238bceSAndroid Build Coastguard Worker return GL_TRIANGLE_STRIP;
229*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_TRIANGLE_FAN:
230*35238bceSAndroid Build Coastguard Worker return GL_TRIANGLE_FAN;
231*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_LINES:
232*35238bceSAndroid Build Coastguard Worker return GL_LINES;
233*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_LINE_STRIP:
234*35238bceSAndroid Build Coastguard Worker return GL_LINE_STRIP;
235*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_LINE_LOOP:
236*35238bceSAndroid Build Coastguard Worker return GL_LINE_LOOP;
237*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_POINTS:
238*35238bceSAndroid Build Coastguard Worker return GL_POINTS;
239*35238bceSAndroid Build Coastguard Worker case PRIMITIVETYPE_PATCHES:
240*35238bceSAndroid Build Coastguard Worker return GL_PATCHES;
241*35238bceSAndroid Build Coastguard Worker default:
242*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
243*35238bceSAndroid Build Coastguard Worker return 0;
244*35238bceSAndroid Build Coastguard Worker }
245*35238bceSAndroid Build Coastguard Worker }
246*35238bceSAndroid Build Coastguard Worker
247*35238bceSAndroid Build Coastguard Worker //! Lower named bindings to locations and eliminate bindings that are not used by program.
248*35238bceSAndroid Build Coastguard Worker template <typename InputIter, typename OutputIter>
namedBindingsToProgramLocations(const glw::Functions & gl,uint32_t program,InputIter first,InputIter end,OutputIter out)249*35238bceSAndroid Build Coastguard Worker static OutputIter namedBindingsToProgramLocations(const glw::Functions &gl, uint32_t program, InputIter first,
250*35238bceSAndroid Build Coastguard Worker InputIter end, OutputIter out)
251*35238bceSAndroid Build Coastguard Worker {
252*35238bceSAndroid Build Coastguard Worker for (InputIter cur = first; cur != end; ++cur)
253*35238bceSAndroid Build Coastguard Worker {
254*35238bceSAndroid Build Coastguard Worker const BindingPoint &binding = cur->binding;
255*35238bceSAndroid Build Coastguard Worker if (binding.type == BindingPoint::BPTYPE_NAME)
256*35238bceSAndroid Build Coastguard Worker {
257*35238bceSAndroid Build Coastguard Worker DE_ASSERT(binding.location >= 0);
258*35238bceSAndroid Build Coastguard Worker int location = gl.getAttribLocation(program, binding.name.c_str());
259*35238bceSAndroid Build Coastguard Worker if (location >= 0)
260*35238bceSAndroid Build Coastguard Worker {
261*35238bceSAndroid Build Coastguard Worker // Add binding.location as an offset to accommodate matrices.
262*35238bceSAndroid Build Coastguard Worker *out = VertexArrayBinding(BindingPoint(location + binding.location), cur->pointer);
263*35238bceSAndroid Build Coastguard Worker ++out;
264*35238bceSAndroid Build Coastguard Worker }
265*35238bceSAndroid Build Coastguard Worker }
266*35238bceSAndroid Build Coastguard Worker else
267*35238bceSAndroid Build Coastguard Worker {
268*35238bceSAndroid Build Coastguard Worker *out = *cur;
269*35238bceSAndroid Build Coastguard Worker ++out;
270*35238bceSAndroid Build Coastguard Worker }
271*35238bceSAndroid Build Coastguard Worker }
272*35238bceSAndroid Build Coastguard Worker
273*35238bceSAndroid Build Coastguard Worker return out;
274*35238bceSAndroid Build Coastguard Worker }
275*35238bceSAndroid Build Coastguard Worker
getMinimumAlignment(const VertexArrayPointer & pointer)276*35238bceSAndroid Build Coastguard Worker static uint32_t getMinimumAlignment(const VertexArrayPointer &pointer)
277*35238bceSAndroid Build Coastguard Worker {
278*35238bceSAndroid Build Coastguard Worker // \todo [2013-05-07 pyry] What is the actual min?
279*35238bceSAndroid Build Coastguard Worker DE_UNREF(pointer);
280*35238bceSAndroid Build Coastguard Worker return (uint32_t)sizeof(float);
281*35238bceSAndroid Build Coastguard Worker }
282*35238bceSAndroid Build Coastguard Worker
283*35238bceSAndroid Build Coastguard Worker template <typename BindingIter>
areVertexArrayLocationsValid(BindingIter first,BindingIter end)284*35238bceSAndroid Build Coastguard Worker static bool areVertexArrayLocationsValid(BindingIter first, BindingIter end)
285*35238bceSAndroid Build Coastguard Worker {
286*35238bceSAndroid Build Coastguard Worker std::set<int> usedLocations;
287*35238bceSAndroid Build Coastguard Worker for (BindingIter cur = first; cur != end; ++cur)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker const BindingPoint &binding = cur->binding;
290*35238bceSAndroid Build Coastguard Worker
291*35238bceSAndroid Build Coastguard Worker if (binding.type != BindingPoint::BPTYPE_LOCATION)
292*35238bceSAndroid Build Coastguard Worker return false;
293*35238bceSAndroid Build Coastguard Worker
294*35238bceSAndroid Build Coastguard Worker if (usedLocations.find(binding.location) != usedLocations.end())
295*35238bceSAndroid Build Coastguard Worker return false;
296*35238bceSAndroid Build Coastguard Worker
297*35238bceSAndroid Build Coastguard Worker usedLocations.insert(binding.location);
298*35238bceSAndroid Build Coastguard Worker }
299*35238bceSAndroid Build Coastguard Worker
300*35238bceSAndroid Build Coastguard Worker return true;
301*35238bceSAndroid Build Coastguard Worker }
302*35238bceSAndroid Build Coastguard Worker
303*35238bceSAndroid Build Coastguard Worker // \todo [2013-05-08 pyry] Buffer upload should try to match pointers to reduce dataset size.
304*35238bceSAndroid Build Coastguard Worker
appendAttributeNonStrided(VertexBufferLayout & layout,const VertexArrayBinding & va)305*35238bceSAndroid Build Coastguard Worker static void appendAttributeNonStrided(VertexBufferLayout &layout, const VertexArrayBinding &va)
306*35238bceSAndroid Build Coastguard Worker {
307*35238bceSAndroid Build Coastguard Worker const int offset = deAlign32(layout.size, getMinimumAlignment(va.pointer));
308*35238bceSAndroid Build Coastguard Worker const int elementSize = getVtxCompSize(va.pointer.componentType) * va.pointer.numComponents;
309*35238bceSAndroid Build Coastguard Worker const int size = elementSize * va.pointer.numElements;
310*35238bceSAndroid Build Coastguard Worker
311*35238bceSAndroid Build Coastguard Worker // Must be assigned to location at this point.
312*35238bceSAndroid Build Coastguard Worker DE_ASSERT(va.binding.type == BindingPoint::BPTYPE_LOCATION);
313*35238bceSAndroid Build Coastguard Worker
314*35238bceSAndroid Build Coastguard Worker layout.attributes.push_back(VertexAttributeDescriptor(va.binding.location, va.pointer.componentType,
315*35238bceSAndroid Build Coastguard Worker va.pointer.convert, va.pointer.numComponents,
316*35238bceSAndroid Build Coastguard Worker va.pointer.numElements,
317*35238bceSAndroid Build Coastguard Worker 0, // default stride
318*35238bceSAndroid Build Coastguard Worker (const void *)(uintptr_t)offset));
319*35238bceSAndroid Build Coastguard Worker layout.size = offset + size;
320*35238bceSAndroid Build Coastguard Worker }
321*35238bceSAndroid Build Coastguard Worker
322*35238bceSAndroid Build Coastguard Worker template <typename BindingIter>
computeNonStridedBufferLayout(VertexBufferLayout & layout,BindingIter first,BindingIter end)323*35238bceSAndroid Build Coastguard Worker static void computeNonStridedBufferLayout(VertexBufferLayout &layout, BindingIter first, BindingIter end)
324*35238bceSAndroid Build Coastguard Worker {
325*35238bceSAndroid Build Coastguard Worker for (BindingIter iter = first; iter != end; ++iter)
326*35238bceSAndroid Build Coastguard Worker appendAttributeNonStrided(layout, *iter);
327*35238bceSAndroid Build Coastguard Worker }
328*35238bceSAndroid Build Coastguard Worker
copyToLayout(void * dstBasePtr,const VertexAttributeDescriptor & dstVA,const VertexArrayPointer & srcPtr)329*35238bceSAndroid Build Coastguard Worker static void copyToLayout(void *dstBasePtr, const VertexAttributeDescriptor &dstVA, const VertexArrayPointer &srcPtr)
330*35238bceSAndroid Build Coastguard Worker {
331*35238bceSAndroid Build Coastguard Worker DE_ASSERT(dstVA.componentType == srcPtr.componentType && dstVA.numComponents == srcPtr.numComponents &&
332*35238bceSAndroid Build Coastguard Worker dstVA.numElements == srcPtr.numElements);
333*35238bceSAndroid Build Coastguard Worker
334*35238bceSAndroid Build Coastguard Worker const int elementSize = getVtxCompSize(dstVA.componentType) * dstVA.numComponents;
335*35238bceSAndroid Build Coastguard Worker const bool srcHasCustomStride = srcPtr.stride != 0 && srcPtr.stride != elementSize;
336*35238bceSAndroid Build Coastguard Worker const bool dstHasCustomStride = dstVA.stride != 0 && dstVA.stride != elementSize;
337*35238bceSAndroid Build Coastguard Worker
338*35238bceSAndroid Build Coastguard Worker if (srcHasCustomStride || dstHasCustomStride)
339*35238bceSAndroid Build Coastguard Worker {
340*35238bceSAndroid Build Coastguard Worker const int dstStride = dstVA.stride != 0 ? dstVA.stride : elementSize;
341*35238bceSAndroid Build Coastguard Worker const int srcStride = srcPtr.stride != 0 ? srcPtr.stride : elementSize;
342*35238bceSAndroid Build Coastguard Worker
343*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < dstVA.numElements; ndx++)
344*35238bceSAndroid Build Coastguard Worker deMemcpy((uint8_t *)dstBasePtr + (uintptr_t)dstVA.pointer + ndx * dstStride,
345*35238bceSAndroid Build Coastguard Worker (const uint8_t *)srcPtr.data + ndx * srcStride, elementSize);
346*35238bceSAndroid Build Coastguard Worker }
347*35238bceSAndroid Build Coastguard Worker else
348*35238bceSAndroid Build Coastguard Worker deMemcpy((uint8_t *)dstBasePtr + (uintptr_t)dstVA.pointer, srcPtr.data, elementSize * dstVA.numElements);
349*35238bceSAndroid Build Coastguard Worker }
350*35238bceSAndroid Build Coastguard Worker
uploadBufferData(const glw::Functions & gl,uint32_t buffer,uint32_t usage,const VertexBufferLayout & layout,const VertexArrayPointer * srcArrays)351*35238bceSAndroid Build Coastguard Worker void uploadBufferData(const glw::Functions &gl, uint32_t buffer, uint32_t usage, const VertexBufferLayout &layout,
352*35238bceSAndroid Build Coastguard Worker const VertexArrayPointer *srcArrays)
353*35238bceSAndroid Build Coastguard Worker {
354*35238bceSAndroid Build Coastguard Worker // Create temporary data buffer for upload.
355*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> localBuf(layout.size);
356*35238bceSAndroid Build Coastguard Worker
357*35238bceSAndroid Build Coastguard Worker for (int attrNdx = 0; attrNdx < (int)layout.attributes.size(); ++attrNdx)
358*35238bceSAndroid Build Coastguard Worker copyToLayout(&localBuf[0], layout.attributes[attrNdx], srcArrays[attrNdx]);
359*35238bceSAndroid Build Coastguard Worker
360*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
361*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ARRAY_BUFFER, (int)localBuf.size(), &localBuf[0], usage);
362*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, 0);
363*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading buffer data failed");
364*35238bceSAndroid Build Coastguard Worker }
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker // VertexBuffer
367*35238bceSAndroid Build Coastguard Worker
VertexBuffer(const RenderContext & context,int numBindings,const VertexArrayBinding * bindings,Type type)368*35238bceSAndroid Build Coastguard Worker VertexBuffer::VertexBuffer(const RenderContext &context, int numBindings, const VertexArrayBinding *bindings, Type type)
369*35238bceSAndroid Build Coastguard Worker : Buffer(context)
370*35238bceSAndroid Build Coastguard Worker {
371*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = context.getFunctions();
372*35238bceSAndroid Build Coastguard Worker const uint32_t usage = GL_STATIC_DRAW;
373*35238bceSAndroid Build Coastguard Worker VertexBufferLayout layout;
374*35238bceSAndroid Build Coastguard Worker
375*35238bceSAndroid Build Coastguard Worker if (!areVertexArrayLocationsValid(bindings, bindings + numBindings))
376*35238bceSAndroid Build Coastguard Worker throw tcu::TestError("Invalid vertex array locations");
377*35238bceSAndroid Build Coastguard Worker
378*35238bceSAndroid Build Coastguard Worker if (type == TYPE_PLANAR)
379*35238bceSAndroid Build Coastguard Worker computeNonStridedBufferLayout(layout, bindings, bindings + numBindings);
380*35238bceSAndroid Build Coastguard Worker else
381*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError("Strided layout is not yet supported");
382*35238bceSAndroid Build Coastguard Worker
383*35238bceSAndroid Build Coastguard Worker std::vector<VertexArrayPointer> srcPtrs(numBindings);
384*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numBindings; ndx++)
385*35238bceSAndroid Build Coastguard Worker srcPtrs[ndx] = bindings[ndx].pointer;
386*35238bceSAndroid Build Coastguard Worker
387*35238bceSAndroid Build Coastguard Worker DE_ASSERT(srcPtrs.size() == layout.attributes.size());
388*35238bceSAndroid Build Coastguard Worker if (!srcPtrs.empty())
389*35238bceSAndroid Build Coastguard Worker uploadBufferData(gl, m_object, usage, layout, &srcPtrs[0]);
390*35238bceSAndroid Build Coastguard Worker
391*35238bceSAndroid Build Coastguard Worker // Construct descriptor.
392*35238bceSAndroid Build Coastguard Worker m_layout.buffer = m_object;
393*35238bceSAndroid Build Coastguard Worker m_layout.attributes = layout.attributes;
394*35238bceSAndroid Build Coastguard Worker }
395*35238bceSAndroid Build Coastguard Worker
~VertexBuffer(void)396*35238bceSAndroid Build Coastguard Worker VertexBuffer::~VertexBuffer(void)
397*35238bceSAndroid Build Coastguard Worker {
398*35238bceSAndroid Build Coastguard Worker }
399*35238bceSAndroid Build Coastguard Worker
400*35238bceSAndroid Build Coastguard Worker // IndexBuffer
401*35238bceSAndroid Build Coastguard Worker
IndexBuffer(const RenderContext & context,IndexType indexType,int numIndices,const void * indices)402*35238bceSAndroid Build Coastguard Worker IndexBuffer::IndexBuffer(const RenderContext &context, IndexType indexType, int numIndices, const void *indices)
403*35238bceSAndroid Build Coastguard Worker : Buffer(context)
404*35238bceSAndroid Build Coastguard Worker {
405*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = context.getFunctions();
406*35238bceSAndroid Build Coastguard Worker const uint32_t usage = GL_STATIC_DRAW;
407*35238bceSAndroid Build Coastguard Worker
408*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_object);
409*35238bceSAndroid Build Coastguard Worker gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * getIndexSize(indexType), indices, usage);
410*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
411*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading index data failed");
412*35238bceSAndroid Build Coastguard Worker }
413*35238bceSAndroid Build Coastguard Worker
~IndexBuffer(void)414*35238bceSAndroid Build Coastguard Worker IndexBuffer::~IndexBuffer(void)
415*35238bceSAndroid Build Coastguard Worker {
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker
getUserPointerDescriptor(const VertexArrayBinding & vertexArray)418*35238bceSAndroid Build Coastguard Worker static inline VertexAttributeDescriptor getUserPointerDescriptor(const VertexArrayBinding &vertexArray)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker DE_ASSERT(vertexArray.binding.type == BindingPoint::BPTYPE_LOCATION);
421*35238bceSAndroid Build Coastguard Worker
422*35238bceSAndroid Build Coastguard Worker return VertexAttributeDescriptor(vertexArray.binding.location, vertexArray.pointer.componentType,
423*35238bceSAndroid Build Coastguard Worker vertexArray.pointer.convert, vertexArray.pointer.numComponents,
424*35238bceSAndroid Build Coastguard Worker vertexArray.pointer.numElements, vertexArray.pointer.stride,
425*35238bceSAndroid Build Coastguard Worker vertexArray.pointer.data);
426*35238bceSAndroid Build Coastguard Worker }
427*35238bceSAndroid Build Coastguard Worker
428*35238bceSAndroid Build Coastguard Worker //! Setup VA according to allocation spec. Assumes that other state (VAO binding, buffer) is set already.
setVertexAttribPointer(const glw::Functions & gl,const VertexAttributeDescriptor & va)429*35238bceSAndroid Build Coastguard Worker static void setVertexAttribPointer(const glw::Functions &gl, const VertexAttributeDescriptor &va)
430*35238bceSAndroid Build Coastguard Worker {
431*35238bceSAndroid Build Coastguard Worker const bool isIntType = de::inRange<int>(va.componentType, VTX_COMP_UNSIGNED_INT8, VTX_COMP_SIGNED_INT32);
432*35238bceSAndroid Build Coastguard Worker const bool isSpecialType = de::inRange<int>(va.componentType, VTX_COMP_FIXED, VTX_COMP_FLOAT);
433*35238bceSAndroid Build Coastguard Worker const uint32_t compTypeGL = getVtxCompGLType(va.componentType);
434*35238bceSAndroid Build Coastguard Worker
435*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isIntType != isSpecialType); // Must be either int or special type.
436*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isIntType || va.convert == VTX_COMP_CONVERT_NONE); // Conversion allowed only for special types.
437*35238bceSAndroid Build Coastguard Worker DE_UNREF(isSpecialType);
438*35238bceSAndroid Build Coastguard Worker
439*35238bceSAndroid Build Coastguard Worker gl.enableVertexAttribArray(va.location);
440*35238bceSAndroid Build Coastguard Worker
441*35238bceSAndroid Build Coastguard Worker if (isIntType && va.convert == VTX_COMP_CONVERT_NONE)
442*35238bceSAndroid Build Coastguard Worker gl.vertexAttribIPointer(va.location, va.numComponents, compTypeGL, va.stride, va.pointer);
443*35238bceSAndroid Build Coastguard Worker else
444*35238bceSAndroid Build Coastguard Worker gl.vertexAttribPointer(va.location, va.numComponents, compTypeGL,
445*35238bceSAndroid Build Coastguard Worker va.convert == VTX_COMP_CONVERT_NORMALIZE_TO_FLOAT ? GL_TRUE : GL_FALSE, va.stride,
446*35238bceSAndroid Build Coastguard Worker va.pointer);
447*35238bceSAndroid Build Coastguard Worker }
448*35238bceSAndroid Build Coastguard Worker
449*35238bceSAndroid Build Coastguard Worker //! Setup vertex buffer and attributes.
setVertexBufferAttributes(const glw::Functions & gl,const VertexBufferDescriptor & buffer)450*35238bceSAndroid Build Coastguard Worker static void setVertexBufferAttributes(const glw::Functions &gl, const VertexBufferDescriptor &buffer)
451*35238bceSAndroid Build Coastguard Worker {
452*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, buffer.buffer);
453*35238bceSAndroid Build Coastguard Worker
454*35238bceSAndroid Build Coastguard Worker for (std::vector<VertexAttributeDescriptor>::const_iterator vaIter = buffer.attributes.begin();
455*35238bceSAndroid Build Coastguard Worker vaIter != buffer.attributes.end(); ++vaIter)
456*35238bceSAndroid Build Coastguard Worker setVertexAttribPointer(gl, *vaIter);
457*35238bceSAndroid Build Coastguard Worker
458*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ARRAY_BUFFER, 0);
459*35238bceSAndroid Build Coastguard Worker }
460*35238bceSAndroid Build Coastguard Worker
disableVertexArrays(const glw::Functions & gl,const std::vector<VertexArrayBinding> & bindings)461*35238bceSAndroid Build Coastguard Worker static void disableVertexArrays(const glw::Functions &gl, const std::vector<VertexArrayBinding> &bindings)
462*35238bceSAndroid Build Coastguard Worker {
463*35238bceSAndroid Build Coastguard Worker for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindings.begin(); vaIter != bindings.end(); ++vaIter)
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker DE_ASSERT(vaIter->binding.type == BindingPoint::BPTYPE_LOCATION);
466*35238bceSAndroid Build Coastguard Worker gl.disableVertexAttribArray(vaIter->binding.location);
467*35238bceSAndroid Build Coastguard Worker }
468*35238bceSAndroid Build Coastguard Worker }
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
isProgramActive(const RenderContext & context,uint32_t program)471*35238bceSAndroid Build Coastguard Worker static bool isProgramActive(const RenderContext &context, uint32_t program)
472*35238bceSAndroid Build Coastguard Worker {
473*35238bceSAndroid Build Coastguard Worker // \todo [2013-05-08 pyry] Is this query broken?
474*35238bceSAndroid Build Coastguard Worker /* uint32_t activeProgram = 0;
475*35238bceSAndroid Build Coastguard Worker context.getFunctions().getIntegerv(GL_ACTIVE_PROGRAM, (int*)&activeProgram);
476*35238bceSAndroid Build Coastguard Worker GLU_EXPECT_NO_ERROR(context.getFunctions().getError(), "oh");
477*35238bceSAndroid Build Coastguard Worker return activeProgram == program;*/
478*35238bceSAndroid Build Coastguard Worker DE_UNREF(context);
479*35238bceSAndroid Build Coastguard Worker DE_UNREF(program);
480*35238bceSAndroid Build Coastguard Worker return true;
481*35238bceSAndroid Build Coastguard Worker }
482*35238bceSAndroid Build Coastguard Worker
isDrawCallValid(int numVertexArrays,const VertexArrayBinding * vertexArrays,const PrimitiveList & primitives)483*35238bceSAndroid Build Coastguard Worker static bool isDrawCallValid(int numVertexArrays, const VertexArrayBinding *vertexArrays,
484*35238bceSAndroid Build Coastguard Worker const PrimitiveList &primitives)
485*35238bceSAndroid Build Coastguard Worker {
486*35238bceSAndroid Build Coastguard Worker if (numVertexArrays < 0)
487*35238bceSAndroid Build Coastguard Worker return false;
488*35238bceSAndroid Build Coastguard Worker
489*35238bceSAndroid Build Coastguard Worker if ((primitives.indexType == INDEXTYPE_LAST) != (primitives.indices == 0))
490*35238bceSAndroid Build Coastguard Worker return false;
491*35238bceSAndroid Build Coastguard Worker
492*35238bceSAndroid Build Coastguard Worker if (primitives.numElements < 0)
493*35238bceSAndroid Build Coastguard Worker return false;
494*35238bceSAndroid Build Coastguard Worker
495*35238bceSAndroid Build Coastguard Worker if (!primitives.indices)
496*35238bceSAndroid Build Coastguard Worker {
497*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < numVertexArrays; ndx++)
498*35238bceSAndroid Build Coastguard Worker {
499*35238bceSAndroid Build Coastguard Worker if (primitives.numElements > vertexArrays[ndx].pointer.numElements)
500*35238bceSAndroid Build Coastguard Worker return false;
501*35238bceSAndroid Build Coastguard Worker }
502*35238bceSAndroid Build Coastguard Worker }
503*35238bceSAndroid Build Coastguard Worker // \todo [2013-05-08 pyry] We could walk whole index array and determine index range
504*35238bceSAndroid Build Coastguard Worker
505*35238bceSAndroid Build Coastguard Worker return true;
506*35238bceSAndroid Build Coastguard Worker }
507*35238bceSAndroid Build Coastguard Worker #endif // DE_DEBUG
508*35238bceSAndroid Build Coastguard Worker
drawNonIndexed(const glw::Functions & gl,PrimitiveType type,int numElements)509*35238bceSAndroid Build Coastguard Worker static inline void drawNonIndexed(const glw::Functions &gl, PrimitiveType type, int numElements)
510*35238bceSAndroid Build Coastguard Worker {
511*35238bceSAndroid Build Coastguard Worker uint32_t mode = getPrimitiveGLType(type);
512*35238bceSAndroid Build Coastguard Worker gl.drawArrays(mode, 0, numElements);
513*35238bceSAndroid Build Coastguard Worker }
514*35238bceSAndroid Build Coastguard Worker
drawIndexed(const glw::Functions & gl,PrimitiveType type,int numElements,IndexType indexType,const void * indexPtr)515*35238bceSAndroid Build Coastguard Worker static inline void drawIndexed(const glw::Functions &gl, PrimitiveType type, int numElements, IndexType indexType,
516*35238bceSAndroid Build Coastguard Worker const void *indexPtr)
517*35238bceSAndroid Build Coastguard Worker {
518*35238bceSAndroid Build Coastguard Worker uint32_t mode = getPrimitiveGLType(type);
519*35238bceSAndroid Build Coastguard Worker uint32_t indexGLType = getIndexGLType(indexType);
520*35238bceSAndroid Build Coastguard Worker
521*35238bceSAndroid Build Coastguard Worker gl.drawElements(mode, numElements, indexGLType, indexPtr);
522*35238bceSAndroid Build Coastguard Worker }
523*35238bceSAndroid Build Coastguard Worker
524*35238bceSAndroid Build Coastguard Worker } // namespace
525*35238bceSAndroid Build Coastguard Worker
drawFromUserPointers(const RenderContext & context,uint32_t program,int numVertexArrays,const VertexArrayBinding * vertexArrays,const PrimitiveList & primitives,DrawUtilCallback * callback)526*35238bceSAndroid Build Coastguard Worker void drawFromUserPointers(const RenderContext &context, uint32_t program, int numVertexArrays,
527*35238bceSAndroid Build Coastguard Worker const VertexArrayBinding *vertexArrays, const PrimitiveList &primitives,
528*35238bceSAndroid Build Coastguard Worker DrawUtilCallback *callback)
529*35238bceSAndroid Build Coastguard Worker {
530*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = context.getFunctions();
531*35238bceSAndroid Build Coastguard Worker std::vector<VertexArrayBinding> bindingsWithLocations;
532*35238bceSAndroid Build Coastguard Worker
533*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isDrawCallValid(numVertexArrays, vertexArrays, primitives));
534*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isProgramActive(context, program));
535*35238bceSAndroid Build Coastguard Worker
536*35238bceSAndroid Build Coastguard Worker // Lower bindings to locations.
537*35238bceSAndroid Build Coastguard Worker namedBindingsToProgramLocations(gl, program, vertexArrays, vertexArrays + numVertexArrays,
538*35238bceSAndroid Build Coastguard Worker std::inserter(bindingsWithLocations, bindingsWithLocations.begin()));
539*35238bceSAndroid Build Coastguard Worker
540*35238bceSAndroid Build Coastguard Worker TCU_CHECK(areVertexArrayLocationsValid(bindingsWithLocations.begin(), bindingsWithLocations.end()));
541*35238bceSAndroid Build Coastguard Worker
542*35238bceSAndroid Build Coastguard Worker // Set VA state.
543*35238bceSAndroid Build Coastguard Worker for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindingsWithLocations.begin();
544*35238bceSAndroid Build Coastguard Worker vaIter != bindingsWithLocations.end(); ++vaIter)
545*35238bceSAndroid Build Coastguard Worker setVertexAttribPointer(gl, getUserPointerDescriptor(*vaIter));
546*35238bceSAndroid Build Coastguard Worker
547*35238bceSAndroid Build Coastguard Worker if (callback)
548*35238bceSAndroid Build Coastguard Worker callback->beforeDrawCall();
549*35238bceSAndroid Build Coastguard Worker
550*35238bceSAndroid Build Coastguard Worker if (primitives.indices)
551*35238bceSAndroid Build Coastguard Worker drawIndexed(gl, primitives.type, primitives.numElements, primitives.indexType, primitives.indices);
552*35238bceSAndroid Build Coastguard Worker else
553*35238bceSAndroid Build Coastguard Worker drawNonIndexed(gl, primitives.type, primitives.numElements);
554*35238bceSAndroid Build Coastguard Worker
555*35238bceSAndroid Build Coastguard Worker if (callback)
556*35238bceSAndroid Build Coastguard Worker callback->afterDrawCall();
557*35238bceSAndroid Build Coastguard Worker
558*35238bceSAndroid Build Coastguard Worker // Disable attribute arrays or otherwise someone later on might get crash thanks to invalid pointers.
559*35238bceSAndroid Build Coastguard Worker disableVertexArrays(gl, bindingsWithLocations);
560*35238bceSAndroid Build Coastguard Worker }
561*35238bceSAndroid Build Coastguard Worker
drawFromBuffers(const RenderContext & context,uint32_t program,int numVertexArrays,const VertexArrayBinding * vertexArrays,const PrimitiveList & primitives,DrawUtilCallback * callback)562*35238bceSAndroid Build Coastguard Worker void drawFromBuffers(const RenderContext &context, uint32_t program, int numVertexArrays,
563*35238bceSAndroid Build Coastguard Worker const VertexArrayBinding *vertexArrays, const PrimitiveList &primitives,
564*35238bceSAndroid Build Coastguard Worker DrawUtilCallback *callback)
565*35238bceSAndroid Build Coastguard Worker {
566*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = context.getFunctions();
567*35238bceSAndroid Build Coastguard Worker std::vector<VertexArrayBinding> bindingsWithLocations;
568*35238bceSAndroid Build Coastguard Worker
569*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isDrawCallValid(numVertexArrays, vertexArrays, primitives));
570*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isProgramActive(context, program));
571*35238bceSAndroid Build Coastguard Worker
572*35238bceSAndroid Build Coastguard Worker // Lower bindings to locations.
573*35238bceSAndroid Build Coastguard Worker namedBindingsToProgramLocations(gl, program, vertexArrays, vertexArrays + numVertexArrays,
574*35238bceSAndroid Build Coastguard Worker std::inserter(bindingsWithLocations, bindingsWithLocations.begin()));
575*35238bceSAndroid Build Coastguard Worker
576*35238bceSAndroid Build Coastguard Worker TCU_CHECK(areVertexArrayLocationsValid(bindingsWithLocations.begin(), bindingsWithLocations.end()));
577*35238bceSAndroid Build Coastguard Worker
578*35238bceSAndroid Build Coastguard Worker // Create buffers for duration of draw call.
579*35238bceSAndroid Build Coastguard Worker {
580*35238bceSAndroid Build Coastguard Worker VertexBuffer vertexBuffer(context, (int)bindingsWithLocations.size(),
581*35238bceSAndroid Build Coastguard Worker (bindingsWithLocations.empty()) ? (DE_NULL) : (&bindingsWithLocations[0]));
582*35238bceSAndroid Build Coastguard Worker
583*35238bceSAndroid Build Coastguard Worker // Set state.
584*35238bceSAndroid Build Coastguard Worker setVertexBufferAttributes(gl, vertexBuffer.getDescriptor());
585*35238bceSAndroid Build Coastguard Worker
586*35238bceSAndroid Build Coastguard Worker if (primitives.indices)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker IndexBuffer indexBuffer(context, primitives.indexType, primitives.numElements, primitives.indices);
589*35238bceSAndroid Build Coastguard Worker
590*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);
591*35238bceSAndroid Build Coastguard Worker
592*35238bceSAndroid Build Coastguard Worker if (callback)
593*35238bceSAndroid Build Coastguard Worker callback->beforeDrawCall();
594*35238bceSAndroid Build Coastguard Worker
595*35238bceSAndroid Build Coastguard Worker drawIndexed(gl, primitives.type, primitives.numElements, primitives.indexType, 0);
596*35238bceSAndroid Build Coastguard Worker
597*35238bceSAndroid Build Coastguard Worker if (callback)
598*35238bceSAndroid Build Coastguard Worker callback->afterDrawCall();
599*35238bceSAndroid Build Coastguard Worker
600*35238bceSAndroid Build Coastguard Worker gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
601*35238bceSAndroid Build Coastguard Worker }
602*35238bceSAndroid Build Coastguard Worker else
603*35238bceSAndroid Build Coastguard Worker {
604*35238bceSAndroid Build Coastguard Worker if (callback)
605*35238bceSAndroid Build Coastguard Worker callback->beforeDrawCall();
606*35238bceSAndroid Build Coastguard Worker
607*35238bceSAndroid Build Coastguard Worker drawNonIndexed(gl, primitives.type, primitives.numElements);
608*35238bceSAndroid Build Coastguard Worker
609*35238bceSAndroid Build Coastguard Worker if (callback)
610*35238bceSAndroid Build Coastguard Worker callback->afterDrawCall();
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker }
613*35238bceSAndroid Build Coastguard Worker
614*35238bceSAndroid Build Coastguard Worker // Disable attribute arrays or otherwise someone later on might get crash thanks to invalid pointers.
615*35238bceSAndroid Build Coastguard Worker for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindingsWithLocations.begin();
616*35238bceSAndroid Build Coastguard Worker vaIter != bindingsWithLocations.end(); ++vaIter)
617*35238bceSAndroid Build Coastguard Worker gl.disableVertexAttribArray(vaIter->binding.location);
618*35238bceSAndroid Build Coastguard Worker }
619*35238bceSAndroid Build Coastguard Worker
drawFromVAOBuffers(const RenderContext & context,uint32_t program,int numVertexArrays,const VertexArrayBinding * vertexArrays,const PrimitiveList & primitives,DrawUtilCallback * callback)620*35238bceSAndroid Build Coastguard Worker void drawFromVAOBuffers(const RenderContext &context, uint32_t program, int numVertexArrays,
621*35238bceSAndroid Build Coastguard Worker const VertexArrayBinding *vertexArrays, const PrimitiveList &primitives,
622*35238bceSAndroid Build Coastguard Worker DrawUtilCallback *callback)
623*35238bceSAndroid Build Coastguard Worker {
624*35238bceSAndroid Build Coastguard Worker const glw::Functions &gl = context.getFunctions();
625*35238bceSAndroid Build Coastguard Worker VertexArray vao(context);
626*35238bceSAndroid Build Coastguard Worker
627*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(*vao);
628*35238bceSAndroid Build Coastguard Worker drawFromBuffers(context, program, numVertexArrays, vertexArrays, primitives, callback);
629*35238bceSAndroid Build Coastguard Worker gl.bindVertexArray(0);
630*35238bceSAndroid Build Coastguard Worker }
631*35238bceSAndroid Build Coastguard Worker
draw(const RenderContext & context,uint32_t program,int numVertexArrays,const VertexArrayBinding * vertexArrays,const PrimitiveList & primitives,DrawUtilCallback * callback)632*35238bceSAndroid Build Coastguard Worker void draw(const RenderContext &context, uint32_t program, int numVertexArrays, const VertexArrayBinding *vertexArrays,
633*35238bceSAndroid Build Coastguard Worker const PrimitiveList &primitives, DrawUtilCallback *callback)
634*35238bceSAndroid Build Coastguard Worker {
635*35238bceSAndroid Build Coastguard Worker const glu::ContextType ctxType = context.getType();
636*35238bceSAndroid Build Coastguard Worker
637*35238bceSAndroid Build Coastguard Worker if (isContextTypeGLCore(ctxType) || contextSupports(ctxType, ApiType::es(3, 1)))
638*35238bceSAndroid Build Coastguard Worker drawFromVAOBuffers(context, program, numVertexArrays, vertexArrays, primitives, callback);
639*35238bceSAndroid Build Coastguard Worker else
640*35238bceSAndroid Build Coastguard Worker {
641*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isContextTypeES(ctxType));
642*35238bceSAndroid Build Coastguard Worker drawFromUserPointers(context, program, numVertexArrays, vertexArrays, primitives, callback);
643*35238bceSAndroid Build Coastguard Worker }
644*35238bceSAndroid Build Coastguard Worker }
645*35238bceSAndroid Build Coastguard Worker
646*35238bceSAndroid Build Coastguard Worker } // namespace glu
647