13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL Utilities 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * --------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Draw call utilities. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator> 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace glu 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VertexAttributeDescriptor 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int location; 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexComponentType componentType; 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexComponentConversion convert; 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numComponents; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numElements; 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int stride; //!< Stride or 0 if using default stride. 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* pointer; //!< Pointer or offset. 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexAttributeDescriptor (int location_, 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexComponentType componentType_, 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexComponentConversion convert_, 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numComponents_, 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numElements_, 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int stride_, 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* pointer_) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : location (location_) 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , componentType (componentType_) 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , convert (convert_) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numComponents (numComponents_) 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numElements (numElements_) 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , stride (stride_) 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , pointer (pointer_) 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexAttributeDescriptor (void) 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : location (0) 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , componentType (VTX_COMP_TYPE_LAST) 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , convert (VTX_COMP_CONVERT_LAST) 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numComponents (0) 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , numElements (0) 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , stride (0) 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , pointer (0) 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VertexBufferLayout 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size; 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexAttributeDescriptor> attributes; 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBufferLayout (int size_ = 0) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : size(size_) 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct VertexBufferDescriptor 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 buffer; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexAttributeDescriptor> attributes; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBufferDescriptor (deUint32 buffer_ = 0) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : buffer(buffer_) 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexBuffer : public Buffer 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum Type 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_PLANAR = 0, //!< Data for each vertex array resides in a separate contiguous block in buffer. 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_STRIDED, //!< Vertex arrays are interleaved. 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TYPE_LAST 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBuffer (const RenderContext& context, int numBindings, const VertexArrayBinding* bindings, Type type = TYPE_PLANAR); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~VertexBuffer (void); 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VertexBufferDescriptor& getDescriptor (void) const { return m_layout; } 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBuffer (const VertexBuffer& other); 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBuffer& operator= (const VertexBuffer& other); 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBufferDescriptor m_layout; 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IndexBuffer : public Buffer 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IndexBuffer (const RenderContext& context, IndexType indexType, int numIndices, const void* indices); 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~IndexBuffer (void); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IndexBuffer (const IndexBuffer& other); 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IndexBuffer& operator= (const IndexBuffer& other); 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getVtxCompGLType (VertexComponentType type) 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT8: return GL_UNSIGNED_BYTE; 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT16: return GL_UNSIGNED_SHORT; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT32: return GL_UNSIGNED_INT; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT8: return GL_BYTE; 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT16: return GL_SHORT; 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT32: return GL_INT; 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_FIXED: return GL_FIXED; 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_HALF_FLOAT: return GL_HALF_FLOAT; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_FLOAT: return GL_FLOAT; 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GL_NONE; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getVtxCompSize (VertexComponentType type) 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT8: return 1; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT16: return 2; 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_UNSIGNED_INT32: return 4; 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT8: return 1; 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT16: return 2; 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_SIGNED_INT32: return 4; 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_FIXED: return 4; 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_HALF_FLOAT: return 2; 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case VTX_COMP_FLOAT: return 4; 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getIndexGLType (IndexType type) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT8: return GL_UNSIGNED_BYTE; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT16: return GL_UNSIGNED_SHORT; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT32: return GL_UNSIGNED_INT; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getIndexSize (IndexType type) 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT8: return 1; 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT16: return 2; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case INDEXTYPE_UINT32: return 4; 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getPrimitiveGLType (PrimitiveType type) 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLES: return GL_TRIANGLES; 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP; 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_TRIANGLE_FAN: return GL_TRIANGLE_FAN; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINES: return GL_LINES; 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINE_STRIP: return GL_LINE_STRIP; 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_LINE_LOOP: return GL_LINE_LOOP; 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_POINTS: return GL_POINTS; 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PRIMITIVETYPE_PATCHES: return GL_PATCHES; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Lower named bindings to locations and eliminate bindings that are not used by program. 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename InputIter, typename OutputIter> 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic OutputIter namedBindingsToProgramLocations (const glw::Functions& gl, deUint32 program, InputIter first, InputIter end, OutputIter out) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (InputIter cur = first; cur != end; ++cur) 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BindingPoint& binding = cur->binding; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (binding.type == BindingPoint::TYPE_NAME) 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(binding.location >= 0); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int location = gl.getAttribLocation(program, binding.name.c_str()); 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (location >= 0) 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Add binding.location as an offset to accommodate matrices. 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *out = VertexArrayBinding(BindingPoint(location + binding.location), cur->pointer); 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++out; 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *out = *cur; 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++out; 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return out; 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getMinimumAlignment (const VertexArrayPointer& pointer) 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-05-07 pyry] What is the actual min? 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(pointer); 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (deUint32)sizeof(float); 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename BindingIter> 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool areVertexArrayLocationsValid (BindingIter first, BindingIter end) 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<int> usedLocations; 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BindingIter cur = first; cur != end; ++cur) 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BindingPoint& binding = cur->binding; 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (binding.type != BindingPoint::TYPE_LOCATION) 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (usedLocations.find(binding.location) != usedLocations.end()) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usedLocations.insert(binding.location); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2013-05-08 pyry] Buffer upload should try to match pointers to reduce dataset size. 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void appendAttributeNonStrided (VertexBufferLayout& layout, const VertexArrayBinding& va) 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int offset = deAlign32(layout.size, getMinimumAlignment(va.pointer)); 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elementSize = getVtxCompSize(va.pointer.componentType)*va.pointer.numComponents; 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int size = elementSize*va.pointer.numElements; 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Must be assigned to location at this point. 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(va.binding.type == BindingPoint::TYPE_LOCATION); 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.attributes.push_back(VertexAttributeDescriptor(va.binding.location, 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry va.pointer.componentType, 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry va.pointer.convert, 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry va.pointer.numComponents, 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry va.pointer.numElements, 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0, // default stride 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (const void*)(deUintptr)offset)); 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.size = offset+size; 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename BindingIter> 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void computeNonStridedBufferLayout (VertexBufferLayout& layout, BindingIter first, BindingIter end) 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BindingIter iter = first; iter != end; ++iter) 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry appendAttributeNonStrided(layout, *iter); 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void copyToLayout (void* dstBasePtr, const VertexAttributeDescriptor& dstVA, const VertexArrayPointer& srcPtr) 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstVA.componentType == srcPtr.componentType && 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dstVA.numComponents == srcPtr.numComponents && 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dstVA.numElements == srcPtr.numElements); 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elementSize = getVtxCompSize(dstVA.componentType)*dstVA.numComponents; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool srcHasCustomStride = srcPtr.stride != 0 && srcPtr.stride != elementSize; 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool dstHasCustomStride = dstVA.stride != 0 && dstVA.stride != elementSize; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (srcHasCustomStride || dstHasCustomStride) 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int dstStride = dstVA.stride != 0 ? dstVA.stride : elementSize; 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int srcStride = srcPtr.stride != 0 ? srcPtr.stride : elementSize; 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < dstVA.numElements; ndx++) 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy((deUint8*)dstBasePtr + (deUintptr)dstVA.pointer + ndx*dstStride, (const deUint8*)srcPtr.data + ndx*srcStride, elementSize); 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy((deUint8*)dstBasePtr + (deUintptr)dstVA.pointer, srcPtr.data, elementSize*dstVA.numElements); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid uploadBufferData (const glw::Functions& gl, deUint32 buffer, deUint32 usage, const VertexBufferLayout& layout, const VertexArrayPointer* srcArrays) 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create temporary data buffer for upload. 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint8> localBuf(layout.size); 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int attrNdx = 0; attrNdx < (int)layout.attributes.size(); ++attrNdx) 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyToLayout(&localBuf[0], layout.attributes[attrNdx], srcArrays[attrNdx]); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, buffer); 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, (int)localBuf.size(), &localBuf[0], usage); 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, 0); 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading buffer data failed"); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// VertexBuffer 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3393c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexBuffer::VertexBuffer (const RenderContext& context, int numBindings, const VertexArrayBinding* bindings, Type type) 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Buffer(context) 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = context.getFunctions(); 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 usage = GL_STATIC_DRAW; 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBufferLayout layout; 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!areVertexArrayLocationsValid(bindings, bindings+numBindings)) 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Invalid vertex array locations"); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type == TYPE_PLANAR) 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry computeNonStridedBufferLayout(layout, bindings, bindings+numBindings); 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::InternalError("Strided layout is not yet supported"); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexArrayPointer> srcPtrs(numBindings); 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numBindings; ndx++) 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry srcPtrs[ndx] = bindings[ndx].pointer; 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(srcPtrs.size() == layout.attributes.size()); 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!srcPtrs.empty()) 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uploadBufferData(gl, m_object, usage, layout, &srcPtrs[0]); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Construct descriptor. 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_layout.buffer = m_object; 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_layout.attributes = layout.attributes; 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexBuffer::~VertexBuffer (void) 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// IndexBuffer 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIndexBuffer::IndexBuffer (const RenderContext& context, IndexType indexType, int numIndices, const void* indices) 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Buffer(context) 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = context.getFunctions(); 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 usage = GL_STATIC_DRAW; 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_object); 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*getIndexSize(indexType), indices, usage); 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading index data failed"); 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIndexBuffer::~IndexBuffer (void) 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline VertexAttributeDescriptor getUserPointerDescriptor (const VertexArrayBinding& vertexArray) 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(vertexArray.binding.type == BindingPoint::TYPE_LOCATION); 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return VertexAttributeDescriptor(vertexArray.binding.location, 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.componentType, 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.convert, 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.numComponents, 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.numElements, 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.stride, 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArray.pointer.data); 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Setup VA according to allocation spec. Assumes that other state (VAO binding, buffer) is set already. 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void setVertexAttribPointer (const glw::Functions& gl, const VertexAttributeDescriptor& va) 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isIntType = de::inRange<int>(va.componentType, VTX_COMP_UNSIGNED_INT8, VTX_COMP_SIGNED_INT32); 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isSpecialType = de::inRange<int>(va.componentType, VTX_COMP_FIXED, VTX_COMP_FLOAT); 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 compTypeGL = getVtxCompGLType(va.componentType); 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isIntType != isSpecialType); // Must be either int or special type. 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isIntType || va.convert == VTX_COMP_CONVERT_NONE); // Conversion allowed only for special types. 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(isSpecialType); 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(va.location); 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isIntType && va.convert == VTX_COMP_CONVERT_NONE) 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribIPointer(va.location, va.numComponents, compTypeGL, va.stride, va.pointer); 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(va.location, va.numComponents, compTypeGL, va.convert == VTX_COMP_CONVERT_NORMALIZE_TO_FLOAT ? GL_TRUE : GL_FALSE, va.stride, va.pointer); 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Setup vertex buffer and attributes. 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void setVertexBufferAttributes (const glw::Functions& gl, const VertexBufferDescriptor& buffer) 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, buffer.buffer); 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<VertexAttributeDescriptor>::const_iterator vaIter = buffer.attributes.begin(); vaIter != buffer.attributes.end(); ++vaIter) 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setVertexAttribPointer(gl, *vaIter); 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, 0); 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void disableVertexArrays (const glw::Functions& gl, const std::vector<VertexArrayBinding>& bindings) 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindings.begin(); vaIter != bindings.end(); ++vaIter) 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(vaIter->binding.type == BindingPoint::TYPE_LOCATION); 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.disableVertexAttribArray(vaIter->binding.location); 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_DEBUG) 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isProgramActive (const RenderContext& context, deUint32 program) 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-05-08 pyry] Is this query broken? 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* deUint32 activeProgram = 0; 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry context.getFunctions().getIntegerv(GL_ACTIVE_PROGRAM, (int*)&activeProgram); 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(context.getFunctions().getError(), "oh"); 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return activeProgram == program;*/ 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(context); 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(program); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isDrawCallValid (int numVertexArrays, const VertexArrayBinding* vertexArrays, const PrimitiveList& primitives) 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numVertexArrays < 0) 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((primitives.indexType == INDEXTYPE_LAST) != (primitives.indices == 0)) 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitives.numElements < 0) 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!primitives.indices) 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numVertexArrays; ndx++) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitives.numElements > vertexArrays[ndx].pointer.numElements) 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-05-08 pyry] We could walk whole index array and determine index range 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // DE_DEBUG 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void drawNonIndexed (const glw::Functions& gl, PrimitiveType type, int numElements) 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 mode = getPrimitiveGLType(type); 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(mode, 0, numElements); 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void drawIndexed (const glw::Functions& gl, PrimitiveType type, int numElements, IndexType indexType, const void* indexPtr) 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 mode = getPrimitiveGLType(type); 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 indexGLType = getIndexGLType(indexType); 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawElements(mode, numElements, indexGLType, indexPtr); 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawFromUserPointers (const RenderContext& context, deUint32 program, int numVertexArrays, const VertexArrayBinding* vertexArrays, const PrimitiveList& primitives, DrawUtilCallback* callback) 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = context.getFunctions(); 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexArrayBinding> bindingsWithLocations; 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isDrawCallValid(numVertexArrays, vertexArrays, primitives)); 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isProgramActive(context, program)); 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Lower bindings to locations. 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry namedBindingsToProgramLocations(gl, program, vertexArrays, vertexArrays+numVertexArrays, std::inserter(bindingsWithLocations, bindingsWithLocations.begin())); 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(areVertexArrayLocationsValid(bindingsWithLocations.begin(), bindingsWithLocations.end())); 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Set VA state. 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindingsWithLocations.begin(); vaIter != bindingsWithLocations.end(); ++vaIter) 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setVertexAttribPointer(gl, getUserPointerDescriptor(*vaIter)); 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->beforeDrawCall(); 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitives.indices) 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawIndexed(gl, primitives.type, primitives.numElements, primitives.indexType, primitives.indices); 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawNonIndexed(gl, primitives.type, primitives.numElements); 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->afterDrawCall(); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Disable attribute arrays or otherwise someone later on might get crash thanks to invalid pointers. 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry disableVertexArrays(gl, bindingsWithLocations); 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawFromBuffers (const RenderContext& context, deUint32 program, int numVertexArrays, const VertexArrayBinding* vertexArrays, const PrimitiveList& primitives, DrawUtilCallback* callback) 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = context.getFunctions(); 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VertexArrayBinding> bindingsWithLocations; 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isDrawCallValid(numVertexArrays, vertexArrays, primitives)); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isProgramActive(context, program)); 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Lower bindings to locations. 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry namedBindingsToProgramLocations(gl, program, vertexArrays, vertexArrays+numVertexArrays, std::inserter(bindingsWithLocations, bindingsWithLocations.begin())); 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(areVertexArrayLocationsValid(bindingsWithLocations.begin(), bindingsWithLocations.end())); 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create buffers for duration of draw call. 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexBuffer vertexBuffer (context, (int)bindingsWithLocations.size(), (bindingsWithLocations.empty()) ? (DE_NULL) : (&bindingsWithLocations[0])); 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Set state. 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setVertexBufferAttributes(gl, vertexBuffer.getDescriptor()); 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitives.indices) 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IndexBuffer indexBuffer(context, primitives.indexType, primitives.numElements, primitives.indices); 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer); 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->beforeDrawCall(); 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawIndexed(gl, primitives.type, primitives.numElements, primitives.indexType, 0); 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->afterDrawCall(); 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->beforeDrawCall(); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawNonIndexed(gl, primitives.type, primitives.numElements); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (callback) 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry callback->afterDrawCall(); 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Disable attribute arrays or otherwise someone later on might get crash thanks to invalid pointers. 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<VertexArrayBinding>::const_iterator vaIter = bindingsWithLocations.begin(); vaIter != bindingsWithLocations.end(); ++vaIter) 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.disableVertexAttribArray(vaIter->binding.location); 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid drawFromVAOBuffers (const RenderContext& context, deUint32 program, int numVertexArrays, const VertexArrayBinding* vertexArrays, const PrimitiveList& primitives, DrawUtilCallback* callback) 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = context.getFunctions(); 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VertexArray vao (context); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawFromBuffers(context, program, numVertexArrays, vertexArrays, primitives, callback); 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(0); 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid draw (const RenderContext& context, deUint32 program, int numVertexArrays, const VertexArrayBinding* vertexArrays, const PrimitiveList& primitives, DrawUtilCallback* callback) 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ContextType ctxType = context.getType(); 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isContextTypeGLCore(ctxType) || contextSupports(ctxType, ApiType::es(3,1))) 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawFromVAOBuffers(context, program, numVertexArrays, vertexArrays, primitives, callback); 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(isContextTypeES(ctxType)); 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawFromUserPointers(context, program, numVertexArrays, vertexArrays, primitives, callback); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // glu 604