13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module 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 SSBO layout case. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fSSBOLayoutCase.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluProgramInterfaceQuery.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarTypeUtil.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h" 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map> 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::VarType; 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::StructType; 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::StructMember; 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace bb 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct LayoutFlagsFmt 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 flags; 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LayoutFlagsFmt (deUint32 flags_) : flags(flags_) {} 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const LayoutFlagsFmt& fmt) 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 bit; 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* token; 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } bitDesc[] = 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_SHARED, "shared" }, 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_PACKED, "packed" }, 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_STD140, "std140" }, 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_STD430, "std430" }, 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_ROW_MAJOR, "row_major" }, 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { LAYOUT_COLUMN_MAJOR, "column_major" } 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 remBits = fmt.flags; 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int descNdx = 0; descNdx < DE_LENGTH_OF_ARRAY(bitDesc); descNdx++) 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (remBits & bitDesc[descNdx].bit) 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (remBits != fmt.flags) 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << ", "; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << bitDesc[descNdx].token; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry remBits &= ~bitDesc[descNdx].bit; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(remBits == 0); 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return str; 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// BufferVar implementation. 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferVar::BufferVar (const char* name, const VarType& type, deUint32 flags) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_name (name) 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_type (type) 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_flags (flags) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// BufferBlock implementation. 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferBlock::BufferBlock (const char* blockName) 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_blockName (blockName) 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_arraySize (-1) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_flags (0) 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setArraySize(0); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BufferBlock::setArraySize (int arraySize) 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(arraySize >= 0); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastUnsizedArraySizes.resize(arraySize == 0 ? 1 : arraySize, 0); 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_arraySize = arraySize; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BlockLayoutEntry 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockLayoutEntry (void) 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : size(0) 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string name; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> activeVarIndices; 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& stream, const BlockLayoutEntry& entry) 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream << entry.name << " { name = " << entry.name 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", size = " << entry.size 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", activeVarIndices = ["; 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator i = entry.activeVarIndices.begin(); i != entry.activeVarIndices.end(); i++) 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (i != entry.activeVarIndices.begin()) 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream << ", "; 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream << *i; 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream << "] }"; 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return stream; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BufferVarLayoutEntry 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry (void) 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : type (glu::TYPE_LAST) 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , blockNdx (-1) 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , offset (-1) 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , arraySize (-1) 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , arrayStride (-1) 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , matrixStride (-1) 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , topLevelArraySize (-1) 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , topLevelArrayStride (-1) 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , isRowMajor (false) 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string name; 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::DataType type; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int blockNdx; 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int offset; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int arraySize; 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int arrayStride; 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int matrixStride; 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int topLevelArraySize; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int topLevelArrayStride; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isRowMajor; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic bool isUnsizedArray (const BufferVarLayoutEntry& entry) 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(entry.arraySize != 0 || entry.topLevelArraySize != 0); 1868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return entry.arraySize == 0 || entry.topLevelArraySize == 0; 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& stream, const BufferVarLayoutEntry& entry) 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream << entry.name << " { type = " << glu::getDataTypeName(entry.type) 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", blockNdx = " << entry.blockNdx 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", offset = " << entry.offset 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", arraySize = " << entry.arraySize 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", arrayStride = " << entry.arrayStride 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", matrixStride = " << entry.matrixStride 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", topLevelArraySize = " << entry.topLevelArraySize 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", topLevelArrayStride = " << entry.topLevelArrayStride 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", isRowMajor = " << (entry.isRowMajor ? "true" : "false") 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " }"; 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return stream; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BufferLayout 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<BlockLayoutEntry> blocks; 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<BufferVarLayoutEntry> bufferVars; 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getVariableIndex (const string& name) const; 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getBlockIndex (const string& name) const; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2012-01-24 pyry] Speed up lookups using hash. 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint BufferLayout::getVariableIndex (const string& name) const 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)bufferVars.size(); ndx++) 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (bufferVars[ndx].name == name) 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ndx; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint BufferLayout::getBlockIndex (const string& name) const 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)blocks.size(); ndx++) 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (blocks[ndx].name == name) 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ndx; 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// ShaderInterface implementation. 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderInterface::ShaderInterface (void) 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderInterface::~ShaderInterface (void) 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<StructType*>::iterator i = m_structs.begin(); i != m_structs.end(); i++) 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete *i; 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<BufferBlock*>::iterator i = m_bufferBlocks.begin(); i != m_bufferBlocks.end(); i++) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete *i; 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryStructType& ShaderInterface::allocStruct (const char* name) 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_structs.reserve(m_structs.size()+1); 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_structs.push_back(new StructType(name)); 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *m_structs.back(); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct StructNameEquals 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string name; 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StructNameEquals (const char* name_) : name(name_) {} 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const StructType* type) const 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return type->getTypeName() && name == type->getTypeName(); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst StructType* ShaderInterface::findStruct (const char* name) const 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<StructType*>::const_iterator pos = std::find_if(m_structs.begin(), m_structs.end(), StructNameEquals(name)); 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return pos != m_structs.end() ? *pos : DE_NULL; 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderInterface::getNamedStructs (std::vector<const StructType*>& structs) const 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<StructType*>::const_iterator i = m_structs.begin(); i != m_structs.end(); i++) 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((*i)->getTypeName() != DE_NULL) 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry structs.push_back(*i); 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferBlock& ShaderInterface::allocBlock (const char* name) 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferBlocks.reserve(m_bufferBlocks.size()+1); 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_bufferBlocks.push_back(new BufferBlock(name)); 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *m_bufferBlocks.back(); 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// BlockDataPtr 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BlockDataPtr 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void* ptr; 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size; //!< Redundant, for debugging purposes. 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int lastUnsizedArraySize; 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_) 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ptr (ptr_) 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , size (size_) 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , lastUnsizedArraySize (lastUnsizedArraySize_) 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockDataPtr (void) 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : ptr (DE_NULL) 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , size (0) 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , lastUnsizedArraySize (0) 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace // Utilities 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint findBlockIndex (const BufferLayout& layout, const string& name) 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)layout.blocks.size(); ndx++) 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (layout.blocks[ndx].name == name) 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ndx; 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Layout computation. 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getDataTypeByteSize (glu::DataType type) 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeScalarSize(type)*sizeof(deUint32); 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint getDataTypeByteAlignment (glu::DataType type) 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT: 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT: 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT: 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL: return 1*sizeof(deUint32); 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC2: 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC2: 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC2: 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC2: return 2*sizeof(deUint32); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC3: 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC3: 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC3: 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC3: // Fall-through to vec4 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC4: 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC4: 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC4: 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC4: return 4*sizeof(deUint32); 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int deRoundUp32 (int a, int b) 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int d = a/b; 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return d*b == a ? a : (d+1)*b; 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint computeStd140BaseAlignment (const VarType& type, deUint32 layoutFlags) 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vec4Alignment = sizeof(deUint32)*4; 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::DataType basicType = type.getBasicType(); 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeMatrix(basicType)) 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecSize = isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumRows(basicType); 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecAlign = deAlign32(getDataTypeByteAlignment(glu::getDataTypeFloatVec(vecSize)), vec4Alignment); 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vecAlign; 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getDataTypeByteAlignment(basicType); 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int elemAlignment = computeStd140BaseAlignment(type.getElementType(), layoutFlags); 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Round up to alignment of vec4 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deAlign32(elemAlignment, vec4Alignment); 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(type.isStructType()); 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxBaseAlignment = 0; 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (StructType::ConstIterator memberIter = type.getStructPtr()->begin(); memberIter != type.getStructPtr()->end(); memberIter++) 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxBaseAlignment = de::max(maxBaseAlignment, computeStd140BaseAlignment(memberIter->getType(), layoutFlags)); 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return deAlign32(maxBaseAlignment, vec4Alignment); 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint computeStd430BaseAlignment (const VarType& type, deUint32 layoutFlags) 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Otherwise identical to std140 except that alignment of structures and arrays 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // are not rounded up to alignment of vec4. 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::DataType basicType = type.getBasicType(); 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeMatrix(basicType)) 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR); 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecSize = isRowMajor ? glu::getDataTypeMatrixNumColumns(basicType) 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumRows(basicType); 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecAlign = getDataTypeByteAlignment(glu::getDataTypeFloatVec(vecSize)); 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vecAlign; 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getDataTypeByteAlignment(basicType); 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return computeStd430BaseAlignment(type.getElementType(), layoutFlags); 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(type.isStructType()); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxBaseAlignment = 0; 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (StructType::ConstIterator memberIter = type.getStructPtr()->begin(); memberIter != type.getStructPtr()->end(); memberIter++) 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxBaseAlignment = de::max(maxBaseAlignment, computeStd430BaseAlignment(memberIter->getType(), layoutFlags)); 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return maxBaseAlignment; 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline deUint32 mergeLayoutFlags (deUint32 prevFlags, deUint32 newFlags) 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 packingMask = LAYOUT_PACKED|LAYOUT_SHARED|LAYOUT_STD140|LAYOUT_STD430; 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 matrixMask = LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR; 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 mergedFlags = 0; 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mergedFlags |= ((newFlags & packingMask) ? newFlags : prevFlags) & packingMask; 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mergedFlags |= ((newFlags & matrixMask) ? newFlags : prevFlags) & matrixMask; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mergedFlags; 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Appends all child elements to layout, returns value that should be appended to offset. 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint computeReferenceLayout ( 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferLayout& layout, 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curBlockNdx, 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int baseOffset, 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string& curPrefix, 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType& type, 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 layoutFlags) 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Reference layout uses std430 rules by default. std140 rules are 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // choosen only for blocks that have std140 layout. 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isStd140 = (layoutFlags & LAYOUT_STD140) != 0; 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int baseAlignment = isStd140 ? computeStd140BaseAlignment(type, layoutFlags) 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : computeStd430BaseAlignment(type, layoutFlags); 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curOffset = deAlign32(baseOffset, baseAlignment); 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int topLevelArraySize = 1; // Default values 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int topLevelArrayStride = 0; 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType basicType = type.getBasicType(); 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry entry; 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = curPrefix; 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = basicType; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = 1; 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = 0; 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = 0; 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = topLevelArraySize; 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = topLevelArrayStride; 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = curBlockNdx; 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeMatrix(basicType)) 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Array of vectors as specified in rules 5 & 7. 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR); 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(basicType) 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumColumns(basicType); 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = baseAlignment; 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.isRowMajor = isRowMajor; 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += numVecs*baseAlignment; 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Scalar or vector. 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += getDataTypeByteSize(basicType); 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.push_back(entry); 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType& elemType = type.getElementType(); 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (elemType.isBasicType() && !glu::isDataTypeMatrix(elemType.getBasicType())) 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Array of scalars or vectors. 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType elemBasicType = elemType.getBasicType(); 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int stride = baseAlignment; 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry entry; 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = curPrefix + "[0]"; // Array variables are always postfixed with [0] 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = elemBasicType; 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = curBlockNdx; 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = type.getArraySize(); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = stride; 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = 0; 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = topLevelArraySize; 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = topLevelArrayStride; 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += stride*type.getArraySize(); 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.push_back(entry); 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (elemType.isBasicType() && glu::isDataTypeMatrix(elemType.getBasicType())) 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Array of matrices. 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType elemBasicType = elemType.getBasicType(); 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isRowMajor = !!(layoutFlags & LAYOUT_ROW_MAJOR); 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(elemBasicType) 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumColumns(elemBasicType); 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecStride = baseAlignment; 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry entry; 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = curPrefix + "[0]"; // Array variables are always postfixed with [0] 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = elemBasicType; 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = curBlockNdx; 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = type.getArraySize(); 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = vecStride*numVecs; 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = vecStride; 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.isRowMajor = isRowMajor; 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = topLevelArraySize; 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = topLevelArrayStride; 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += numVecs*vecStride*type.getArraySize(); 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.push_back(entry); 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(elemType.isStructType() || elemType.isArrayType()); 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elemNdx = 0; elemNdx < type.getArraySize(); elemNdx++) 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += computeReferenceLayout(layout, curBlockNdx, curOffset, curPrefix + "[" + de::toString(elemNdx) + "]", type.getElementType(), layoutFlags); 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(type.isStructType()); 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (StructType::ConstIterator memberIter = type.getStructPtr()->begin(); memberIter != type.getStructPtr()->end(); memberIter++) 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += computeReferenceLayout(layout, curBlockNdx, curOffset, curPrefix + "." + memberIter->getName(), memberIter->getType(), layoutFlags); 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset = deAlign32(curOffset, baseAlignment); 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return curOffset-baseOffset; 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Appends all child elements to layout, returns offset increment. 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint computeReferenceLayout (BufferLayout& layout, int curBlockNdx, const std::string& blockPrefix, int baseOffset, const BufferVar& bufVar, deUint32 blockLayoutFlags) 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType& varType = bufVar.getType(); 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 combinedFlags = mergeLayoutFlags(blockLayoutFlags, bufVar.getFlags()); 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (varType.isArrayType()) 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Top-level arrays need special care. 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int topLevelArraySize = varType.getArraySize() == VarType::UNSIZED_ARRAY ? 0 : varType.getArraySize(); 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string prefix = blockPrefix + bufVar.getName() + "[0]"; 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isStd140 = (blockLayoutFlags & LAYOUT_STD140) != 0; 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vec4Align = sizeof(deUint32)*4; 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int baseAlignment = isStd140 ? computeStd140BaseAlignment(varType, combinedFlags) 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : computeStd430BaseAlignment(varType, combinedFlags); 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curOffset = deAlign32(baseOffset, baseAlignment); 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType& elemType = varType.getElementType(); 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (elemType.isBasicType() && !glu::isDataTypeMatrix(elemType.getBasicType())) 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Array of scalars or vectors. 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType elemBasicType = elemType.getBasicType(); 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elemBaseAlign = getDataTypeByteAlignment(elemBasicType); 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int stride = isStd140 ? deAlign32(elemBaseAlign, vec4Align) : elemBaseAlign; 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry entry; 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = prefix; 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = 1; 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = 0; 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = elemBasicType; 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = curBlockNdx; 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = topLevelArraySize; 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = stride; 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = 0; 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.push_back(entry); 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += stride*topLevelArraySize; 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (elemType.isBasicType() && glu::isDataTypeMatrix(elemType.getBasicType())) 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Array of matrices. 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType elemBasicType = elemType.getBasicType(); 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isRowMajor = !!(combinedFlags & LAYOUT_ROW_MAJOR); 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecSize = isRowMajor ? glu::getDataTypeMatrixNumColumns(elemBasicType) 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumRows(elemBasicType); 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVecs = isRowMajor ? glu::getDataTypeMatrixNumRows(elemBasicType) 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::getDataTypeMatrixNumColumns(elemBasicType); 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType vecType = glu::getDataTypeFloatVec(vecSize); 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecBaseAlign = getDataTypeByteAlignment(vecType); 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int stride = isStd140 ? deAlign32(vecBaseAlign, vec4Align) : vecBaseAlign; 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry entry; 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = prefix; 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = 1; 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = 0; 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = elemBasicType; 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = curBlockNdx; 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = curOffset; 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = topLevelArraySize; 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = stride*numVecs; 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = stride; 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.isRowMajor = isRowMajor; 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.push_back(entry); 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += stride*numVecs*topLevelArraySize; 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(elemType.isStructType() || elemType.isArrayType()); 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Struct base alignment is not added multiple times as curOffset supplied to computeReferenceLayout 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // was already aligned correctly. Thus computeReferenceLayout should not add any extra padding 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // before struct. Padding after struct will be added as it should. 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Stride could be computed prior to creating child elements, but it would essentially require running 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // the layout computation twice. Instead we fix stride to child elements afterwards. 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int firstChildNdx = (int)layout.bufferVars.size(); 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int stride = computeReferenceLayout(layout, curBlockNdx, curOffset, prefix, varType.getElementType(), combinedFlags); 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int childNdx = firstChildNdx; childNdx < (int)layout.bufferVars.size(); childNdx++) 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars[childNdx].topLevelArraySize = topLevelArraySize; 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars[childNdx].topLevelArrayStride = stride; 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += stride*topLevelArraySize; 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return curOffset-baseOffset; 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return computeReferenceLayout(layout, curBlockNdx, baseOffset, blockPrefix + bufVar.getName(), varType, combinedFlags); 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid computeReferenceLayout (BufferLayout& layout, const ShaderInterface& interface) 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = interface.getNumBlocks(); 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(blockNdx); 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool hasInstanceName = block.getInstanceName() != DE_NULL; 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string blockPrefix = hasInstanceName ? (std::string(block.getBlockName()) + ".") : std::string(""); 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curOffset = 0; 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int activeBlockNdx = (int)layout.blocks.size(); 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int firstVarNdx = (int)layout.bufferVars.size(); 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++) 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar = *varIter; 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += computeReferenceLayout(layout, activeBlockNdx, blockPrefix, curOffset, bufVar, block.getFlags()); 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int varIndicesEnd = (int)layout.bufferVars.size(); 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int blockSize = curOffset; 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = block.isArray() ? block.getArraySize() : 1; 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create block layout entries for each instance. 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Allocate entry for instance. 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.blocks.push_back(BlockLayoutEntry()); 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockLayoutEntry& blockEntry = layout.blocks.back(); 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockEntry.name = block.getBlockName(); 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockEntry.size = blockSize; 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute active variable set for block. 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = firstVarNdx; varNdx < varIndicesEnd; varNdx++) 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockEntry.activeVarIndices.push_back(varNdx); 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.isArray()) 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockEntry.name += "[" + de::toString(instanceNdx) + "]"; 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Value generator. 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid generateValue (const BufferVarLayoutEntry& entry, int unsizedArraySize, void* basePtr, de::Random& rnd) 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType scalarType = glu::getDataTypeScalarType(entry.type); 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(entry.type); 7358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int arraySize = entry.arraySize == 0 ? unsizedArraySize : entry.arraySize; 7368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int arrayStride = entry.arrayStride; 7378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int topLevelSize = entry.topLevelArraySize == 0 ? unsizedArraySize : entry.topLevelArraySize; 7388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int topLevelStride = entry.topLevelArrayStride; 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(entry.type); 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVecs = isMatrix ? (entry.isRowMajor ? glu::getDataTypeMatrixNumRows(entry.type) : glu::getDataTypeMatrixNumColumns(entry.type)) : 1; 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecSize = scalarSize / numVecs; 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(scalarSize%numVecs == 0); 7458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(topLevelSize >= 0); 7468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(arraySize >= 0); 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int topElemNdx = 0; topElemNdx < topLevelSize; topElemNdx++) 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const topElemPtr = (deUint8*)basePtr + entry.offset + topElemNdx*topLevelStride; 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elemNdx = 0; elemNdx < arraySize; elemNdx++) 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const elemPtr = topElemPtr + elemNdx*arrayStride; 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vecNdx = 0; vecNdx < numVecs; vecNdx++) 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const vecPtr = elemPtr + (isMatrix ? vecNdx*entry.matrixStride : 0); 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int compNdx = 0; compNdx < vecSize; compNdx++) 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const compPtr = vecPtr + compSize*compNdx; 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (scalarType) 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT: *((float*)compPtr) = (float)rnd.getInt(-9, 9); break; 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT: *((int*)compPtr) = rnd.getInt(-9, 9); break; 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT: *((deUint32*)compPtr) = (deUint32)rnd.getInt(0, 9); break; 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Random bit pattern is used for true values. Spec states that all non-zero values are 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // interpreted as true but some implementations fail this. 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL: *((deUint32*)compPtr) = rnd.getBool() ? rnd.getUint32()|1u : 0u; break; 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateValues (const BufferLayout& layout, const vector<BlockDataPtr>& blockPointers, deUint32 seed) 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (seed); 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBlocks = (int)layout.blocks.size(); 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numBlocks == (int)blockPointers.size()); 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& blockLayout = layout.blocks[blockNdx]; 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& blockPtr = blockPointers[blockNdx]; 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numEntries = (int)layout.blocks[blockNdx].activeVarIndices.size(); 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int entryNdx = 0; entryNdx < numEntries; entryNdx++) 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int varNdx = blockLayout.activeVarIndices[entryNdx]; 7978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const BufferVarLayoutEntry& varEntry = layout.bufferVars[varNdx]; 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry generateValue(varEntry, blockPtr.lastUnsizedArraySize, blockPtr.ptr, rnd); 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Shader generator. 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* getCompareFuncForType (glu::DataType type) 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT: return "bool compare_float (highp float a, highp float b) { return abs(a - b) < 0.05; }\n"; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC2: return "bool compare_vec2 (highp vec2 a, highp vec2 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y); }\n"; 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC3: return "bool compare_vec3 (highp vec3 a, highp vec3 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z); }\n"; 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC4: return "bool compare_vec4 (highp vec4 a, highp vec4 b) { return compare_float(a.x, b.x)&&compare_float(a.y, b.y)&&compare_float(a.z, b.z)&&compare_float(a.w, b.w); }\n"; 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2: return "bool compare_mat2 (highp mat2 a, highp mat2 b) { return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1]); }\n"; 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2X3: return "bool compare_mat2x3 (highp mat2x3 a, highp mat2x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1]); }\n"; 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2X4: return "bool compare_mat2x4 (highp mat2x4 a, highp mat2x4 b){ return compare_vec4(a[0], b[0])&&compare_vec4(a[1], b[1]); }\n"; 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3X2: return "bool compare_mat3x2 (highp mat3x2 a, highp mat3x2 b){ return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2]); }\n"; 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3: return "bool compare_mat3 (highp mat3 a, highp mat3 b) { return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2]); }\n"; 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3X4: return "bool compare_mat3x4 (highp mat3x4 a, highp mat3x4 b){ return compare_vec4(a[0], b[0])&&compare_vec4(a[1], b[1])&&compare_vec4(a[2], b[2]); }\n"; 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4X2: return "bool compare_mat4x2 (highp mat4x2 a, highp mat4x2 b){ return compare_vec2(a[0], b[0])&&compare_vec2(a[1], b[1])&&compare_vec2(a[2], b[2])&&compare_vec2(a[3], b[3]); }\n"; 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4X3: return "bool compare_mat4x3 (highp mat4x3 a, highp mat4x3 b){ return compare_vec3(a[0], b[0])&&compare_vec3(a[1], b[1])&&compare_vec3(a[2], b[2])&&compare_vec3(a[3], b[3]); }\n"; 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4: return "bool compare_mat4 (highp mat4 a, highp mat4 b) { return compare_vec4(a[0], b[0])&&compare_vec4(a[1], b[1])&&compare_vec4(a[2], b[2])&&compare_vec4(a[3], b[3]); }\n"; 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT: return "bool compare_int (highp int a, highp int b) { return a == b; }\n"; 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC2: return "bool compare_ivec2 (highp ivec2 a, highp ivec2 b) { return a == b; }\n"; 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC3: return "bool compare_ivec3 (highp ivec3 a, highp ivec3 b) { return a == b; }\n"; 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT_VEC4: return "bool compare_ivec4 (highp ivec4 a, highp ivec4 b) { return a == b; }\n"; 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT: return "bool compare_uint (highp uint a, highp uint b) { return a == b; }\n"; 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC2: return "bool compare_uvec2 (highp uvec2 a, highp uvec2 b) { return a == b; }\n"; 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC3: return "bool compare_uvec3 (highp uvec3 a, highp uvec3 b) { return a == b; }\n"; 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT_VEC4: return "bool compare_uvec4 (highp uvec4 a, highp uvec4 b) { return a == b; }\n"; 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL: return "bool compare_bool (bool a, bool b) { return a == b; }\n"; 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC2: return "bool compare_bvec2 (bvec2 a, bvec2 b) { return a == b; }\n"; 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC3: return "bool compare_bvec3 (bvec3 a, bvec3 b) { return a == b; }\n"; 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL_VEC4: return "bool compare_bvec4 (bvec4 a, bvec4 b) { return a == b; }\n"; 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid getCompareDependencies (std::set<glu::DataType>& compareFuncs, glu::DataType basicType) 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (basicType) 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC2: 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC3: 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_VEC4: 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(glu::TYPE_FLOAT); 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(basicType); 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2: 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2X3: 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT2X4: 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3X2: 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3: 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT3X4: 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4X2: 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4X3: 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT_MAT4: 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(glu::TYPE_FLOAT); 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(glu::getDataTypeFloatVec(glu::getDataTypeMatrixNumRows(basicType))); 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(basicType); 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry compareFuncs.insert(basicType); 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid collectUniqueBasicTypes (std::set<glu::DataType>& basicTypes, const VarType& type) 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isStructType()) 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (StructType::ConstIterator iter = type.getStructPtr()->begin(); iter != type.getStructPtr()->end(); ++iter) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectUniqueBasicTypes(basicTypes, iter->getType()); 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectUniqueBasicTypes(basicTypes, type.getElementType()); 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(type.isBasicType()); 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry basicTypes.insert(type.getBasicType()); 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid collectUniqueBasicTypes (std::set<glu::DataType>& basicTypes, const BufferBlock& bufferBlock) 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator iter = bufferBlock.begin(); iter != bufferBlock.end(); ++iter) 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectUniqueBasicTypes(basicTypes, iter->getType()); 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid collectUniqueBasicTypes (std::set<glu::DataType>& basicTypes, const ShaderInterface& interface) 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < interface.getNumBlocks(); ++ndx) 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectUniqueBasicTypes(basicTypes, interface.getBlock(ndx)); 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateCompareFuncs (std::ostream& str, const ShaderInterface& interface) 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<glu::DataType> types; 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<glu::DataType> compareFuncs; 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Collect unique basic types 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectUniqueBasicTypes(types, interface); 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Set of compare functions required 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::set<glu::DataType>::const_iterator iter = types.begin(); iter != types.end(); ++iter) 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getCompareDependencies(compareFuncs, *iter); 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int type = 0; type < glu::TYPE_LAST; ++type) 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (compareFuncs.find(glu::DataType(type)) != compareFuncs.end()) 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << getCompareFuncForType(glu::DataType(type)); 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Indent 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int level; 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Indent (int level_) : level(level_) {} 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::ostream& operator<< (std::ostream& str, const Indent& indent) 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < indent.level; i++) 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry str << "\t"; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return str; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateDeclaration (std::ostream& src, const BufferVar& bufferVar, int indentLevel) 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [pyry] Qualifiers 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((bufferVar.getFlags() & LAYOUT_MASK) != 0) 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "layout(" << LayoutFlagsFmt(bufferVar.getFlags() & LAYOUT_MASK) << ") "; 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << glu::declare(bufferVar.getType(), bufferVar.getName(), indentLevel); 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateDeclaration (std::ostream& src, const BufferBlock& block, int bindingPoint) 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "layout("; 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((block.getFlags() & LAYOUT_MASK) != 0) 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << LayoutFlagsFmt(block.getFlags() & LAYOUT_MASK) << ", "; 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "binding = " << bindingPoint; 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ") "; 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "buffer " << block.getBlockName(); 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n{\n"; 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++) 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << Indent(1); 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateDeclaration(src, *varIter, 1 /* indent level */); 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ";\n"; 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "}"; 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.getInstanceName() != DE_NULL) 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " " << block.getInstanceName(); 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.isArray()) 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "[" << block.getArraySize() << "]"; 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!block.isArray()); 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ";\n"; 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateImmMatrixSrc (std::ostream& src, glu::DataType basicType, int matrixStride, bool isRowMajor, const void* valuePtr) 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(glu::isDataTypeMatrix(basicType)); 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numRows = glu::getDataTypeMatrixNumRows(basicType); 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numCols = glu::getDataTypeMatrixNumColumns(basicType); 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << glu::getDataTypeName(basicType) << "("; 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Constructed in column-wise order. 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int colNdx = 0; colNdx < numCols; colNdx++) 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rowNdx = 0; rowNdx < numRows; rowNdx++) 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* compPtr = (const deUint8*)valuePtr + (isRowMajor ? rowNdx*matrixStride + colNdx*compSize 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : colNdx*matrixStride + rowNdx*compSize); 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (colNdx > 0 || rowNdx > 0) 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ", "; 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << de::floatToString(*((const float*)compPtr), 1); 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ")"; 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateImmScalarVectorSrc (std::ostream& src, glu::DataType basicType, const void* valuePtr) 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(glu::isDataTypeFloatOrVec(basicType) || 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::isDataTypeIntOrIVec(basicType) || 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::isDataTypeUintOrUVec(basicType) || 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::isDataTypeBoolOrBVec(basicType)); 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType scalarType = glu::getDataTypeScalarType(basicType); 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(basicType); 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (scalarSize > 1) 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << glu::getDataTypeName(basicType) << "("; 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* compPtr = (const deUint8*)valuePtr + scalarNdx*compSize; 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (scalarNdx > 0) 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ", "; 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (scalarType) 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_FLOAT: src << de::floatToString(*((const float*)compPtr), 1); break; 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_INT: src << *((const int*)compPtr); break; 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_UINT: src << *((const deUint32*)compPtr) << "u"; break; 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::TYPE_BOOL: src << (*((const deUint32*)compPtr) != 0u ? "true" : "false"); break; 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (scalarSize > 1) 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ")"; 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring getAPIName (const BufferBlock& block, const BufferVar& var, const glu::TypeComponentVector& accessPath) 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream name; 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.getInstanceName()) 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << block.getBlockName() << "."; 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << var.getName(); 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (glu::TypeComponentVector::const_iterator pathComp = accessPath.begin(); pathComp != accessPath.end(); pathComp++) 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pathComp->type == glu::VarTypeComponent::STRUCT_MEMBER) 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType curType = glu::getVarType(var.getType(), accessPath.begin(), pathComp); 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const StructType* structPtr = curType.getStructPtr(); 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "." << structPtr->getMember(pathComp->index).getName(); 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (pathComp->type == glu::VarTypeComponent::ARRAY_ELEMENT) 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pathComp == accessPath.begin() || (pathComp+1) == accessPath.end()) 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[0]"; // Top- / bottom-level array 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << pathComp->index << "]"; 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return name.str(); 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring getShaderName (const BufferBlock& block, int instanceNdx, const BufferVar& var, const glu::TypeComponentVector& accessPath) 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream name; 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.getInstanceName()) 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << block.getInstanceName(); 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.isArray()) 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << instanceNdx << "]"; 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "."; 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(instanceNdx == 0); 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << var.getName(); 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (glu::TypeComponentVector::const_iterator pathComp = accessPath.begin(); pathComp != accessPath.end(); pathComp++) 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pathComp->type == glu::VarTypeComponent::STRUCT_MEMBER) 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType curType = glu::getVarType(var.getType(), accessPath.begin(), pathComp); 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const StructType* structPtr = curType.getStructPtr(); 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "." << structPtr->getMember(pathComp->index).getName(); 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (pathComp->type == glu::VarTypeComponent::ARRAY_ELEMENT) 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << pathComp->index << "]"; 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return name.str(); 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint computeOffset (const BufferVarLayoutEntry& varLayout, const glu::TypeComponentVector& accessPath) 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int topLevelNdx = (accessPath.size() > 1 && accessPath.front().type == glu::VarTypeComponent::ARRAY_ELEMENT) ? accessPath.front().index : 0; 11148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int bottomLevelNdx = (!accessPath.empty() && accessPath.back().type == glu::VarTypeComponent::ARRAY_ELEMENT) ? accessPath.back().index : 0; 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return varLayout.offset + varLayout.topLevelArrayStride*topLevelNdx + varLayout.arrayStride*bottomLevelNdx; 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateCompareSrc ( 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostream& src, 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* resultVar, 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferLayout& bufferLayout, 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block, 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int instanceNdx, 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& blockPtr, 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar, 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::SubTypeAccess& accessPath) 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType curType = accessPath.getType(); 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curType.isArrayType()) 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ? block.getLastUnsizedArraySize(instanceNdx) : curType.getArraySize(); 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elemNdx = 0; elemNdx < arraySize; elemNdx++) 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateCompareSrc(src, resultVar, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.element(elemNdx)); 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curType.isStructType()) 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMembers = curType.getStructPtr()->getNumMembers(); 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < numMembers; memberNdx++) 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateCompareSrc(src, resultVar, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.member(memberNdx)); 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(curType.isBasicType()); 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string apiName = getAPIName(block, bufVar, accessPath.getPath()); 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int varNdx = bufferLayout.getVariableIndex(apiName); 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(varNdx >= 0); 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& varLayout = bufferLayout.bufferVars[varNdx]; 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string shaderName = getShaderName(block, instanceNdx, bufVar, accessPath.getPath()); 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType basicType = curType.getBasicType(); 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(basicType); 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* typeName = glu::getDataTypeName(basicType); 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* valuePtr = (const deUint8*)blockPtr.ptr + computeOffset(varLayout, accessPath.getPath()); 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\t" << resultVar << " = " << resultVar << " && compare_" << typeName << "(" << shaderName << ", "; 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMatrix) 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmMatrixSrc(src, basicType, varLayout.matrixStride, varLayout.isRowMajor, valuePtr); 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmScalarVectorSrc(src, basicType, valuePtr); 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ");\n"; 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateCompareSrc (std::ostream& src, const char* resultVar, const ShaderInterface& interface, const BufferLayout& layout, const vector<BlockDataPtr>& blockPointers) 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++) 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(declNdx); 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = block.isArray(); 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInstances = isArray ? block.getArraySize() : 1; 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isArray || block.getInstanceName()); 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string instanceName = block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string("")); 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int blockNdx = layout.getBlockIndex(instanceName); 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& blockPtr = blockPointers[blockNdx]; 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++) 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar = *varIter; 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((bufVar.getFlags() & ACCESS_READ) == 0) 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Don't read from that variable. 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateCompareSrc(src, resultVar, layout, block, instanceNdx, blockPtr, bufVar, glu::SubTypeAccess(bufVar.getType())); 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2013-10-14 pyry] Almost identical to generateCompareSrc - unify? 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateWriteSrc ( 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostream& src, 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferLayout& bufferLayout, 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block, 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int instanceNdx, 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& blockPtr, 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar, 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::SubTypeAccess& accessPath) 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType curType = accessPath.getType(); 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curType.isArrayType()) 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ? block.getLastUnsizedArraySize(instanceNdx) : curType.getArraySize(); 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elemNdx = 0; elemNdx < arraySize; elemNdx++) 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateWriteSrc(src, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.element(elemNdx)); 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curType.isStructType()) 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMembers = curType.getStructPtr()->getNumMembers(); 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < numMembers; memberNdx++) 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateWriteSrc(src, bufferLayout, block, instanceNdx, blockPtr, bufVar, accessPath.member(memberNdx)); 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(curType.isBasicType()); 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string apiName = getAPIName(block, bufVar, accessPath.getPath()); 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int varNdx = bufferLayout.getVariableIndex(apiName); 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(varNdx >= 0); 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& varLayout = bufferLayout.bufferVars[varNdx]; 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string shaderName = getShaderName(block, instanceNdx, bufVar, accessPath.getPath()); 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType basicType = curType.getBasicType(); 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(basicType); 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* valuePtr = (const deUint8*)blockPtr.ptr + computeOffset(varLayout, accessPath.getPath()); 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\t" << shaderName << " = "; 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMatrix) 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmMatrixSrc(src, basicType, varLayout.matrixStride, varLayout.isRowMajor, valuePtr); 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmScalarVectorSrc(src, basicType, valuePtr); 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << ";\n"; 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid generateWriteSrc (std::ostream& src, const ShaderInterface& interface, const BufferLayout& layout, const vector<BlockDataPtr>& blockPointers) 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++) 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(declNdx); 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = block.isArray(); 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInstances = isArray ? block.getArraySize() : 1; 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isArray || block.getInstanceName()); 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string instanceName = block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string("")); 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int blockNdx = layout.getBlockIndex(instanceName); 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& blockPtr = blockPointers[blockNdx]; 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++) 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar = *varIter; 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((bufVar.getFlags() & ACCESS_WRITE) == 0) 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Don't write to that variable. 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateWriteSrc(src, layout, block, instanceNdx, blockPtr, bufVar, glu::SubTypeAccess(bufVar.getType())); 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring generateComputeShader (glu::GLSLVersion glslVersion, const ShaderInterface& interface, const BufferLayout& layout, const vector<BlockDataPtr>& comparePtrs, const vector<BlockDataPtr>& writePtrs) 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream src; 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion == glu::GLSL_VERSION_430); 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "layout(local_size_x = 1) in;\n"; 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n"; 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const StructType*> namedStructs; 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry interface.getNamedStructs(namedStructs); 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::vector<const StructType*>::const_iterator structIter = namedStructs.begin(); structIter != namedStructs.end(); structIter++) 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << glu::declare(*structIter) << ";\n"; 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bindingPoint = 0; 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < interface.getNumBlocks(); blockNdx++) 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(blockNdx); 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateDeclaration(src, block, bindingPoint); 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bindingPoint += block.isArray() ? block.getArraySize() : 1; 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Atomic counter for counting passed invocations. 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\nlayout(binding = 0) uniform atomic_uint ac_numPassed;\n"; 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Comparison utilities. 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n"; 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateCompareFuncs(src, interface); 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "\n" 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " bool allOk = true;\n"; 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Value compare. 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateCompareSrc(src, "allOk", interface, layout, comparePtrs); 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << " if (allOk)\n" 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " atomicCounterIncrement(ac_numPassed);\n" 13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Value write. 13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateWriteSrc(src, interface, layout, writePtrs); 13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src << "}\n"; 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return src.str(); 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid getGLBufferLayout (const glw::Functions& gl, BufferLayout& layout, deUint32 program) 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numActiveBufferVars = 0; 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numActiveBlocks = 0; 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramInterfaceiv(program, GL_BUFFER_VARIABLE, GL_ACTIVE_RESOURCES, &numActiveBufferVars); 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &numActiveBlocks); 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get number of buffer variables and buffer blocks"); 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Block entries. 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.blocks.resize(numActiveBlocks); 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numActiveBlocks; blockNdx++) 13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockLayoutEntry& entry = layout.blocks[blockNdx]; 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 queryParams[] = { GL_BUFFER_DATA_SIZE, GL_NUM_ACTIVE_VARIABLES, GL_NAME_LENGTH }; 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int returnValues[] = { 0, 0, 0 }; 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(queryParams) == DE_LENGTH_OF_ARRAY(returnValues)); 13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int returnLength = 0; 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, (deUint32)blockNdx, DE_LENGTH_OF_ARRAY(queryParams), &queryParams[0], DE_LENGTH_OF_ARRAY(returnValues), &returnLength, &returnValues[0]); 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK) failed"); 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (returnLength != DE_LENGTH_OF_ARRAY(returnValues)) 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK) returned wrong number of values"); 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.size = returnValues[0]; 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Query active variables 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (returnValues[1] > 0) 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBlockVars = returnValues[1]; 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 queryArg = GL_ACTIVE_VARIABLES; 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retLength = 0; 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.activeVarIndices.resize(numBlockVars); 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, (deUint32)blockNdx, 1, &queryArg, numBlockVars, &retLength, &entry.activeVarIndices[0]); 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_VARIABLES) failed"); 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (retLength != numBlockVars) 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceiv(GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_VARIABLES) returned wrong number of values"); 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Query name 13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (returnValues[2] > 0) 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int nameLen = returnValues[2]; 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retLen = 0; 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<char> name (nameLen); 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, (deUint32)blockNdx, (glw::GLsizei)name.size(), &retLen, &name[0]); 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) failed"); 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (retLen+1 != nameLen) 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) returned invalid name. Number of characters written is inconsistent with NAME_LENGTH property."); 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (name[nameLen-1] != 0) 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceName(GL_SHADER_STORAGE_BLOCK) returned invalid name. Expected null terminator at index " + de::toString(nameLen-1)); 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = &name[0]; 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceiv() returned invalid GL_NAME_LENGTH"); 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry layout.bufferVars.resize(numActiveBufferVars); 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int bufVarNdx = 0; bufVarNdx < numActiveBufferVars; bufVarNdx++) 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferVarLayoutEntry& entry = layout.bufferVars[bufVarNdx]; 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 queryParams[] = 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_BLOCK_INDEX, // 0 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_TYPE, // 1 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_OFFSET, // 2 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_ARRAY_SIZE, // 3 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_ARRAY_STRIDE, // 4 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_MATRIX_STRIDE, // 5 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_TOP_LEVEL_ARRAY_SIZE, // 6 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_TOP_LEVEL_ARRAY_STRIDE, // 7 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_IS_ROW_MAJOR, // 8 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GL_NAME_LENGTH // 9 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int returnValues[DE_LENGTH_OF_ARRAY(queryParams)]; 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(queryParams) == DE_LENGTH_OF_ARRAY(returnValues)); 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int returnLength = 0; 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceiv(program, GL_BUFFER_VARIABLE, (deUint32)bufVarNdx, DE_LENGTH_OF_ARRAY(queryParams), &queryParams[0], DE_LENGTH_OF_ARRAY(returnValues), &returnLength, &returnValues[0]); 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceiv(GL_BUFFER_VARIABLE) failed"); 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (returnLength != DE_LENGTH_OF_ARRAY(returnValues)) 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceiv(GL_BUFFER_VARIABLE) returned wrong number of values"); 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Map values 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.blockNdx = returnValues[0]; 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.type = glu::getDataTypeFromGLType(returnValues[1]); 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.offset = returnValues[2]; 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arraySize = returnValues[3]; 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.arrayStride = returnValues[4]; 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.matrixStride = returnValues[5]; 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArraySize = returnValues[6]; 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.topLevelArrayStride = returnValues[7]; 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.isRowMajor = returnValues[8] != 0; 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Query name 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(queryParams[9] == GL_NAME_LENGTH); 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (returnValues[9] > 0) 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int nameLen = returnValues[9]; 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retLen = 0; 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<char> name (nameLen); 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceName(program, GL_BUFFER_VARIABLE, (deUint32)bufVarNdx, (glw::GLsizei)name.size(), &retLen, &name[0]); 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceName(GL_BUFFER_VARIABLE) failed"); 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (retLen+1 != nameLen) 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceName(GL_BUFFER_VARIABLE) returned invalid name. Number of characters written is inconsistent with NAME_LENGTH property."); 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (name[nameLen-1] != 0) 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceName(GL_BUFFER_VARIABLE) returned invalid name. Expected null terminator at index " + de::toString(nameLen-1)); 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry entry.name = &name[0]; 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("glGetProgramResourceiv() returned invalid GL_NAME_LENGTH"); 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyBufferVarData (const BufferVarLayoutEntry& dstEntry, const BlockDataPtr& dstBlockPtr, const BufferVarLayoutEntry& srcEntry, const BlockDataPtr& srcBlockPtr) 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstEntry.arraySize <= srcEntry.arraySize); 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstEntry.topLevelArraySize <= srcEntry.topLevelArraySize); 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstBlockPtr.lastUnsizedArraySize <= srcBlockPtr.lastUnsizedArraySize); 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstEntry.type == srcEntry.type); 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const dstBasePtr = (deUint8*)dstBlockPtr.ptr + dstEntry.offset; 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const srcBasePtr = (const deUint8*)srcBlockPtr.ptr + srcEntry.offset; 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(dstEntry.type); 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(dstEntry.type); 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 14828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int dstArraySize = dstEntry.arraySize == 0 ? dstBlockPtr.lastUnsizedArraySize : dstEntry.arraySize; 14838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int dstArrayStride = dstEntry.arrayStride; 14848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int dstTopLevelSize = dstEntry.topLevelArraySize == 0 ? dstBlockPtr.lastUnsizedArraySize : dstEntry.topLevelArraySize; 14858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int dstTopLevelStride = dstEntry.topLevelArrayStride; 14868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int srcArraySize = srcEntry.arraySize == 0 ? srcBlockPtr.lastUnsizedArraySize : srcEntry.arraySize; 14878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int srcArrayStride = srcEntry.arrayStride; 14888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int srcTopLevelSize = srcEntry.topLevelArraySize == 0 ? srcBlockPtr.lastUnsizedArraySize : srcEntry.topLevelArraySize; 14898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int srcTopLevelStride = srcEntry.topLevelArrayStride; 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(dstArraySize <= srcArraySize && dstTopLevelSize <= srcTopLevelSize); 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(srcArraySize && srcTopLevelSize); 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int topElemNdx = 0; topElemNdx < dstTopLevelSize; topElemNdx++) 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const dstTopPtr = dstBasePtr + topElemNdx*dstTopLevelStride; 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const srcTopPtr = srcBasePtr + topElemNdx*srcTopLevelStride; 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elementNdx = 0; elementNdx < dstArraySize; elementNdx++) 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const dstElemPtr = dstTopPtr + elementNdx*dstArrayStride; 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const srcElemPtr = srcTopPtr + elementNdx*srcArrayStride; 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMatrix) 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numRows = glu::getDataTypeMatrixNumRows(dstEntry.type); 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numCols = glu::getDataTypeMatrixNumColumns(dstEntry.type); 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int colNdx = 0; colNdx < numCols; colNdx++) 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rowNdx = 0; rowNdx < numRows; rowNdx++) 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* dstCompPtr = dstElemPtr + (dstEntry.isRowMajor ? rowNdx*dstEntry.matrixStride + colNdx*compSize 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : colNdx*dstEntry.matrixStride + rowNdx*compSize); 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* srcCompPtr = srcElemPtr + (srcEntry.isRowMajor ? rowNdx*srcEntry.matrixStride + colNdx*compSize 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : colNdx*srcEntry.matrixStride + rowNdx*compSize); 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(srcCompPtr + compSize) - (deIntptr)srcBlockPtr.ptr <= (deIntptr)srcBlockPtr.size); 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(dstCompPtr + compSize) - (deIntptr)dstBlockPtr.ptr <= (deIntptr)dstBlockPtr.size); 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(dstCompPtr, srcCompPtr, compSize); 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(srcElemPtr + scalarSize*compSize) - (deIntptr)srcBlockPtr.ptr <= (deIntptr)srcBlockPtr.size); 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(dstElemPtr + scalarSize*compSize) - (deIntptr)dstBlockPtr.ptr <= (deIntptr)dstBlockPtr.size); 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(dstElemPtr, srcElemPtr, scalarSize*compSize); 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyData (const BufferLayout& dstLayout, const vector<BlockDataPtr>& dstBlockPointers, const BufferLayout& srcLayout, const vector<BlockDataPtr>& srcBlockPointers) 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Src layout is used as reference in case of activeVarIndices happens to be incorrect in dstLayout blocks. 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = (int)srcLayout.blocks.size(); 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int srcBlockNdx = 0; srcBlockNdx < numBlocks; srcBlockNdx++) 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& srcBlock = srcLayout.blocks[srcBlockNdx]; 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& srcBlockPtr = srcBlockPointers[srcBlockNdx]; 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int dstBlockNdx = dstLayout.getBlockIndex(srcBlock.name.c_str()); 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (dstBlockNdx >= 0) 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inBounds(dstBlockNdx, 0, (int)dstBlockPointers.size())); 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& dstBlockPtr = dstBlockPointers[dstBlockNdx]; 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator srcVarNdxIter = srcBlock.activeVarIndices.begin(); srcVarNdxIter != srcBlock.activeVarIndices.end(); srcVarNdxIter++) 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& srcEntry = srcLayout.bufferVars[*srcVarNdxIter]; 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int dstVarNdx = dstLayout.getVariableIndex(srcEntry.name.c_str()); 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (dstVarNdx >= 0) 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyBufferVarData(dstLayout.bufferVars[dstVarNdx], dstBlockPtr, srcEntry, srcBlockPtr); 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyNonWrittenData ( 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferLayout& layout, 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block, 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int instanceNdx, 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& srcBlockPtr, 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& dstBlockPtr, 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar, 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::SubTypeAccess& accessPath) 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VarType curType = accessPath.getType(); 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curType.isArrayType()) 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = curType.getArraySize() == VarType::UNSIZED_ARRAY ? block.getLastUnsizedArraySize(instanceNdx) : curType.getArraySize(); 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elemNdx = 0; elemNdx < arraySize; elemNdx++) 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar, accessPath.element(elemNdx)); 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (curType.isStructType()) 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMembers = curType.getStructPtr()->getNumMembers(); 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < numMembers; memberNdx++) 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar, accessPath.member(memberNdx)); 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(curType.isBasicType()); 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string apiName = getAPIName(block, bufVar, accessPath.getPath()); 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int varNdx = layout.getVariableIndex(apiName); 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(varNdx >= 0); 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& varLayout = layout.bufferVars[varNdx]; 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyBufferVarData(varLayout, dstBlockPtr, varLayout, srcBlockPtr); 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid copyNonWrittenData (const ShaderInterface& interface, const BufferLayout& layout, const vector<BlockDataPtr>& srcPtrs, const vector<BlockDataPtr>& dstPtrs) 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++) 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(declNdx); 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = block.isArray(); 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInstances = isArray ? block.getArraySize() : 1; 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!isArray || block.getInstanceName()); 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string instanceName = block.getBlockName() + (isArray ? "[" + de::toString(instanceNdx) + "]" : string("")); 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int blockNdx = layout.getBlockIndex(instanceName); 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& srcBlockPtr = srcPtrs[blockNdx]; 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& dstBlockPtr = dstPtrs[blockNdx]; 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (BufferBlock::const_iterator varIter = block.begin(); varIter != block.end(); varIter++) 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVar& bufVar = *varIter; 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (bufVar.getFlags() & ACCESS_WRITE) 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyNonWrittenData(layout, block, instanceNdx, srcBlockPtr, dstBlockPtr, bufVar, glu::SubTypeAccess(bufVar.getType())); 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool compareComponents (glu::DataType scalarType, const void* ref, const void* res, int numComps) 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (scalarType == glu::TYPE_FLOAT) 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float threshold = 0.05f; // Same as used in shaders - should be fine for values being used. 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numComps; ndx++) 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float refVal = *((const float*)ref + ndx); 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float resVal = *((const float*)res + ndx); 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deFloatAbs(resVal - refVal) >= threshold) 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (scalarType == glu::TYPE_BOOL) 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numComps; ndx++) 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 refVal = *((const deUint32*)ref + ndx); 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 resVal = *((const deUint32*)res + ndx); 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((refVal != 0) != (resVal != 0)) 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(scalarType == glu::TYPE_INT || scalarType == glu::TYPE_UINT); 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < numComps; ndx++) 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 refVal = *((const deUint32*)ref + ndx); 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 resVal = *((const deUint32*)res + ndx); 16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refVal != resVal) 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool compareBufferVarData (tcu::TestLog& log, const BufferVarLayoutEntry& refEntry, const BlockDataPtr& refBlockPtr, const BufferVarLayoutEntry& resEntry, const BlockDataPtr& resBlockPtr) 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(resEntry.arraySize <= refEntry.arraySize); 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(resEntry.topLevelArraySize <= refEntry.topLevelArraySize); 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(resBlockPtr.lastUnsizedArraySize <= refBlockPtr.lastUnsizedArraySize); 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(resEntry.type == refEntry.type); 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const resBasePtr = (deUint8*)resBlockPtr.ptr + resEntry.offset; 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const refBasePtr = (const deUint8*)refBlockPtr.ptr + refEntry.offset; 16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::DataType scalarType = glu::getDataTypeScalarType(refEntry.type); 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(resEntry.type); 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(resEntry.type); 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxPrints = 3; 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numFailed = 0; 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int resArraySize = resEntry.arraySize == 0 ? resBlockPtr.lastUnsizedArraySize : resEntry.arraySize; 16938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int resArrayStride = resEntry.arrayStride; 16948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int resTopLevelSize = resEntry.topLevelArraySize == 0 ? resBlockPtr.lastUnsizedArraySize : resEntry.topLevelArraySize; 16958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int resTopLevelStride = resEntry.topLevelArrayStride; 16968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int refArraySize = refEntry.arraySize == 0 ? refBlockPtr.lastUnsizedArraySize : refEntry.arraySize; 16978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int refArrayStride = refEntry.arrayStride; 16988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int refTopLevelSize = refEntry.topLevelArraySize == 0 ? refBlockPtr.lastUnsizedArraySize : refEntry.topLevelArraySize; 16998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int refTopLevelStride = refEntry.topLevelArrayStride; 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(resArraySize <= refArraySize && resTopLevelSize <= refTopLevelSize); 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(refArraySize && refTopLevelSize); 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int topElemNdx = 0; topElemNdx < resTopLevelSize; topElemNdx++) 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const resTopPtr = resBasePtr + topElemNdx*resTopLevelStride; 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const refTopPtr = refBasePtr + topElemNdx*refTopLevelStride; 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int elementNdx = 0; elementNdx < resArraySize; elementNdx++) 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* const resElemPtr = resTopPtr + elementNdx*resArrayStride; 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* const refElemPtr = refTopPtr + elementNdx*refArrayStride; 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMatrix) 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numRows = glu::getDataTypeMatrixNumRows(resEntry.type); 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numCols = glu::getDataTypeMatrixNumColumns(resEntry.type); 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int colNdx = 0; colNdx < numCols; colNdx++) 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rowNdx = 0; rowNdx < numRows; rowNdx++) 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* resCompPtr = resElemPtr + (resEntry.isRowMajor ? rowNdx*resEntry.matrixStride + colNdx*compSize 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : colNdx*resEntry.matrixStride + rowNdx*compSize); 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint8* refCompPtr = refElemPtr + (refEntry.isRowMajor ? rowNdx*refEntry.matrixStride + colNdx*compSize 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : colNdx*refEntry.matrixStride + rowNdx*compSize); 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(refCompPtr + compSize) - (deIntptr)refBlockPtr.ptr <= (deIntptr)refBlockPtr.size); 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(resCompPtr + compSize) - (deIntptr)resBlockPtr.ptr <= (deIntptr)resBlockPtr.size); 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = isOk && compareComponents(scalarType, resCompPtr, refCompPtr, 1); 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isOk) 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numFailed += 1; 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numFailed < maxPrints) 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream expected, got; 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmMatrixSrc(expected, refEntry.type, refEntry.matrixStride, refEntry.isRowMajor, refElemPtr); 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmMatrixSrc(got, resEntry.type, resEntry.matrixStride, resEntry.isRowMajor, resElemPtr); 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "ERROR: mismatch in " << refEntry.name << ", top-level ndx " << topElemNdx << ", bottom-level ndx " << elementNdx << ":\n" 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " expected " << expected.str() << "\n" 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " got " << got.str() 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(refElemPtr + scalarSize*compSize) - (deIntptr)refBlockPtr.ptr <= (deIntptr)refBlockPtr.size); 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((deIntptr)(resElemPtr + scalarSize*compSize) - (deIntptr)resBlockPtr.ptr <= (deIntptr)resBlockPtr.size); 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isOk = compareComponents(scalarType, resElemPtr, refElemPtr, scalarSize); 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isOk) 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numFailed += 1; 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numFailed < maxPrints) 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream expected, got; 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmScalarVectorSrc(expected, refEntry.type, refElemPtr); 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateImmScalarVectorSrc(got, resEntry.type, resElemPtr); 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "ERROR: mismatch in " << refEntry.name << ", top-level ndx " << topElemNdx << ", bottom-level ndx " << elementNdx << ":\n" 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " expected " << expected.str() << "\n" 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " got " << got.str() 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numFailed >= maxPrints) 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "... (" << numFailed << " failures for " << refEntry.name << " in total)" << TestLog::EndMessage; 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numFailed == 0; 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool compareData (tcu::TestLog& log, const BufferLayout& refLayout, const vector<BlockDataPtr>& refBlockPointers, const BufferLayout& resLayout, const vector<BlockDataPtr>& resBlockPointers) 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBlocks = (int)refLayout.blocks.size(); 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int refBlockNdx = 0; refBlockNdx < numBlocks; refBlockNdx++) 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& refBlock = refLayout.blocks[refBlockNdx]; 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& refBlockPtr = refBlockPointers[refBlockNdx]; 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int resBlockNdx = resLayout.getBlockIndex(refBlock.name.c_str()); 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resBlockNdx >= 0) 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inBounds(resBlockNdx, 0, (int)resBlockPointers.size())); 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockDataPtr& resBlockPtr = resBlockPointers[resBlockNdx]; 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator refVarNdxIter = refBlock.activeVarIndices.begin(); refVarNdxIter != refBlock.activeVarIndices.end(); refVarNdxIter++) 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& refEntry = refLayout.bufferVars[*refVarNdxIter]; 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int resVarNdx = resLayout.getVariableIndex(refEntry.name.c_str()); 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resVarNdx >= 0) 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& resEntry = resLayout.bufferVars[resVarNdx]; 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk = compareBufferVarData(log, refEntry, refBlockPtr, resEntry, resBlockPtr) && allOk; 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring getBlockAPIName (const BufferBlock& block, int instanceNdx) 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(block.isArray() || instanceNdx == 0); 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return block.getBlockName() + (block.isArray() ? ("[" + de::toString(instanceNdx) + "]") : string()); 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// \note Some implementations don't report block members in the order they are declared. 18238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// For checking whether size has to be adjusted by some top-level array actual size, 18248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// we only need to know a) whether there is a unsized top-level array, and b) 18258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// what is stride of that array. 18268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic bool hasUnsizedArray (const BufferLayout& layout, const BlockLayoutEntry& entry) 18288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 18298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (vector<int>::const_iterator varNdx = entry.activeVarIndices.begin(); varNdx != entry.activeVarIndices.end(); ++varNdx) 18308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 18318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (isUnsizedArray(layout.bufferVars[*varNdx])) 18328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return true; 18338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 18348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return false; 18368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 18378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic int getUnsizedArrayStride (const BufferLayout& layout, const BlockLayoutEntry& entry) 18398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 18408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (vector<int>::const_iterator varNdx = entry.activeVarIndices.begin(); varNdx != entry.activeVarIndices.end(); ++varNdx) 18418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 18428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const BufferVarLayoutEntry& varEntry = layout.bufferVars[*varNdx]; 18438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (varEntry.arraySize == 0) 18458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return varEntry.arrayStride; 18468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (varEntry.topLevelArraySize == 0) 18478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return varEntry.topLevelArrayStride; 18488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 18498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return 0; 18518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 18528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<int> computeBufferSizes (const ShaderInterface& interface, const BufferLayout& layout) 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<int> sizes(layout.blocks.size()); 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int declNdx = 0; declNdx < interface.getNumBlocks(); declNdx++) 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = interface.getBlock(declNdx); 18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = block.isArray(); 18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInstances = isArray ? block.getArraySize() : 1; 18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string apiName = getBlockAPIName(block, instanceNdx); 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int blockNdx = layout.getBlockIndex(apiName); 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (blockNdx >= 0) 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& blockLayout = layout.blocks[blockNdx]; 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int baseSize = blockLayout.size; 18728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool isLastUnsized = hasUnsizedArray(layout, blockLayout); 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int lastArraySize = isLastUnsized ? block.getLastUnsizedArraySize(instanceNdx) : 0; 18748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int stride = isLastUnsized ? getUnsizedArrayStride(layout, blockLayout) : 0; 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sizes[blockNdx] = baseSize + lastArraySize*stride; 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sizes; 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockDataPtr getBlockDataPtr (const BufferLayout& layout, const BlockLayoutEntry& blockLayout, void* ptr, int bufferSize) 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool isLastUnsized = hasUnsizedArray(layout, blockLayout); 18878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int baseSize = blockLayout.size; 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isLastUnsized) 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int lastArrayStride = getUnsizedArrayStride(layout, blockLayout); 18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int lastArraySize = (bufferSize-baseSize) / (lastArrayStride ? lastArrayStride : 1); 18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(baseSize + lastArraySize*lastArrayStride == bufferSize); 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return BlockDataPtr(ptr, bufferSize, lastArraySize); 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return BlockDataPtr(ptr, bufferSize, 0); 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct RefDataStorage 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint8> data; 19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<BlockDataPtr> pointers; 19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Buffer 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 buffer; 19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size; 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Buffer (deUint32 buffer_, int size_) : buffer(buffer_), size(size_) {} 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Buffer (void) : buffer(0), size(0) {} 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct BlockLocation 19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int index; 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int offset; 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size; 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockLocation (int index_, int offset_, int size_) : index(index_), offset(offset_), size(size_) {} 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockLocation (void) : index(0), offset(0), size(0) {} 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid initRefDataStorage (const ShaderInterface& interface, const BufferLayout& layout, RefDataStorage& storage) 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(storage.data.empty() && storage.pointers.empty()); 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<int> bufferSizes = computeBufferSizes(interface, layout); 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int totalSize = 0; 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator sizeIter = bufferSizes.begin(); sizeIter != bufferSizes.end(); ++sizeIter) 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry totalSize += *sizeIter; 19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry storage.data.resize(totalSize); 19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Pointers for each block. 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* basePtr = storage.data.empty() ? DE_NULL : &storage.data[0]; 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curOffset = 0; 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(bufferSizes.size() == layout.blocks.size()); 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(totalSize == 0 || basePtr); 19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry storage.pointers.resize(layout.blocks.size()); 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++) 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& blockLayout = layout.blocks[blockNdx]; 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferSizes[blockNdx]; 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry storage.pointers[blockNdx] = getBlockDataPtr(layout, blockLayout, basePtr + curOffset, bufferSize); 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += bufferSize; 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<BlockDataPtr> blockLocationsToPtrs (const BufferLayout& layout, const vector<BlockLocation>& blockLocations, const vector<void*>& bufPtrs) 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<BlockDataPtr> blockPtrs(blockLocations.size()); 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(layout.blocks.size() == blockLocations.size()); 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++) 19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& blockLayout = layout.blocks[blockNdx]; 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLocation& location = blockLocations[blockNdx]; 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockPtrs[blockNdx] = getBlockDataPtr(layout, blockLayout, (deUint8*)bufPtrs[location.index] + location.offset, location.size); 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return blockPtrs; 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<void*> mapBuffers (const glw::Functions& gl, const vector<Buffer>& buffers, deUint32 access) 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<void*> mapPtrs(buffers.size(), DE_NULL); 19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)buffers.size(); ndx++) 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers[ndx].size > 0) 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer); 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mapPtrs[ndx] = gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffers[ndx].size, access); 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to map buffer"); 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(mapPtrs[ndx]); 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mapPtrs[ndx] = DE_NULL; 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return mapPtrs; 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (...) 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)buffers.size(); ndx++) 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (mapPtrs[ndx]) 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer); 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw; 20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid unmapBuffers (const glw::Functions& gl, const vector<Buffer>& buffers) 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)buffers.size(); ndx++) 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (buffers[ndx].size > 0) 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[ndx].buffer); 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unmap buffer"); 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous (utilities) 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BufferManager 20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferManager (const glu::RenderContext& renderCtx); 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~BufferManager (void); 20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 allocBuffer (void); 20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferManager (const BufferManager& other); 20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferManager& operator= (const BufferManager& other); 20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::RenderContext& m_renderCtx; 20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<deUint32> m_buffers; 20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferManager::BufferManager (const glu::RenderContext& renderCtx) 20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_renderCtx(renderCtx) 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferManager::~BufferManager (void) 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_buffers.empty()) 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_renderCtx.getFunctions().deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]); 20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20573c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 BufferManager::allocBuffer (void) 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 buf = 0; 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffers.reserve(m_buffers.size()+1); 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_renderCtx.getFunctions().genBuffers(1, &buf); 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(m_renderCtx.getFunctions().getError(), "Failed to allocate buffer"); 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffers.push_back(buf); 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf; 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // bb 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace bb; 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// SSBOLayoutCase. 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20753c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOLayoutCase::SSBOLayoutCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, glu::GLSLVersion glslVersion, BufferMode bufferMode) 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (testCtx, name, description) 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_renderCtx (renderCtx) 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_glslVersion (glslVersion) 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bufferMode (bufferMode) 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion == glu::GLSL_VERSION_430); 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20843c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOLayoutCase::~SSBOLayoutCase (void) 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20883c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySSBOLayoutCase::IterateResult SSBOLayoutCase::iterate (void) 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderCtx.getFunctions(); 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferLayout refLayout; // std140 / std430 layout. 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferLayout glLayout; // Layout reported by GL. 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RefDataStorage initialData; // Initial data stored in buffer. 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RefDataStorage writeData; // Data written by compute shader. 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferManager bufferManager (m_renderCtx); 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Buffer> buffers; // Buffers allocated for storage 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<BlockLocation> blockLocations; // Block locations in storage (index, offset) 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize result to pass. 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry computeReferenceLayout (refLayout, m_interface); 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initRefDataStorage (m_interface, refLayout, initialData); 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry initRefDataStorage (m_interface, refLayout, writeData); 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateValues (refLayout, initialData.pointers, deStringHash(getName()) ^ 0xad2f7214); 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generateValues (refLayout, writeData.pointers, deStringHash(getName()) ^ 0x25ca4e7); 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyNonWrittenData (m_interface, refLayout, initialData.pointers, writeData.pointers); 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ShaderProgram program(m_renderCtx, glu::ProgramSources() << glu::ComputeSource(generateComputeShader(m_glslVersion, m_interface, refLayout, initialData.pointers, writeData.pointers))); 21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << program; 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program.isOk()) 21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compile failed. 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compile failed"); 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Query layout from GL. 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getGLBufferLayout(gl, glLayout, program.getProgram()); 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Print layout to log. 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::ScopedLogSection section(log, "ActiveBufferBlocks", "Active Buffer Blocks"); 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)glLayout.blocks.size(); blockNdx++) 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << blockNdx << ": " << glLayout.blocks[blockNdx] << TestLog::EndMessage; 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::ScopedLogSection section(log, "ActiveBufferVars", "Active Buffer Variables"); 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)glLayout.bufferVars.size(); varNdx++) 21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << varNdx << ": " << glLayout.bufferVars[varNdx] << TestLog::EndMessage; 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify layouts. 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!checkLayoutIndices(glLayout) || !checkLayoutBounds(glLayout) || !compareTypes(refLayout, glLayout)) 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid layout"); 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; // It is not safe to use the given layout. 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!compareStdBlocks(refLayout, glLayout)) 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid std140 or std430 layout"); 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!compareSharedBlocks(refLayout, glLayout)) 21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid shared layout"); 21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!checkIndexQueries(program.getProgram(), glLayout)) 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsintent block index query results"); 21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Allocate GL buffers & compute placement. 21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBlocks = (int)glLayout.blocks.size(); 21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<int> bufferSizes = computeBufferSizes(m_interface, glLayout); 21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(bufferSizes.size() == glLayout.blocks.size()); 21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockLocations.resize(numBlocks); 21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_bufferMode == BUFFERMODE_PER_BLOCK) 21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.resize(numBlocks); 21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferSizes[blockNdx]; 21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers[blockNdx].size = bufferSize; 21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockLocations[blockNdx] = BlockLocation(blockNdx, 0, bufferSize); 21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_bufferMode == BUFFERMODE_SINGLE); 21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bindingAlignment = 0; 21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int totalSize = 0; 21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &bindingAlignment); 21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int curOffset = 0; 21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(bufferSizes.size() == glLayout.blocks.size()); 21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = bufferSizes[blockNdx]; 21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (bindingAlignment > 0) 21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset = deRoundUp32(curOffset, bindingAlignment); 21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockLocations[blockNdx] = BlockLocation(0, curOffset, bufferSize); 21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curOffset += bufferSize; 21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry totalSize = curOffset; 22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.resize(1); 22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers[0].size = totalSize; 22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int bufNdx = 0; bufNdx < (int)buffers.size(); bufNdx++) 22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = buffers[bufNdx].size; 22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 buffer = bufferManager.allocBuffer(); 22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); 22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_SHADER_STORAGE_BUFFER, bufferSize, DE_NULL, GL_STATIC_DRAW); 22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to allocate buffer"); 22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers[bufNdx].buffer = buffer; 22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<void*> mapPtrs = mapBuffers(gl, buffers, GL_MAP_WRITE_BIT); 22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<BlockDataPtr> mappedBlockPtrs = blockLocationsToPtrs(glLayout, blockLocations, mapPtrs); 22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry copyData(glLayout, mappedBlockPtrs, refLayout, initialData.pointers); 22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry unmapBuffers(gl, buffers); 22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bindingPoint = 0; 22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockDeclNdx = 0; blockDeclNdx < m_interface.getNumBlocks(); blockDeclNdx++) 22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = m_interface.getBlock(blockDeclNdx); 22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInst = block.isArray() ? block.getArraySize() : 1; 22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instNdx = 0; instNdx < numInst; instNdx++) 22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string instName = getBlockAPIName(block, instNdx); 22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int layoutNdx = findBlockIndex(glLayout, instName); 22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (layoutNdx >= 0) 22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLocation& blockLoc = blockLocations[layoutNdx]; 22448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 22458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (blockLoc.size > 0) 22468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, bindingPoint, buffers[blockLoc.index].buffer, blockLoc.offset, blockLoc.size); 22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bindingPoint += 1; 22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind buffers"); 22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool execOk = execute(program.getProgram()); 22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (execOk) 22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<void*> mapPtrs = mapBuffers(gl, buffers, GL_MAP_READ_BIT); 22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<BlockDataPtr> mappedBlockPtrs = blockLocationsToPtrs(glLayout, blockLocations, mapPtrs); 22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool compareOk = compareData(m_testCtx.getLog(), refLayout, writeData.pointers, glLayout, mappedBlockPtrs); 22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry unmapBuffers(gl, buffers); 22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!compareOk) 22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed"); 22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Shader execution failed"); 22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::compareStdBlocks (const BufferLayout& refLayout, const BufferLayout& cmpLayout) const 22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = m_interface.getNumBlocks(); 22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = m_interface.getBlock(blockNdx); 22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isArray = block.isArray(); 22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string instanceName = string(block.getBlockName()) + (isArray ? "[0]" : ""); 22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int refBlockNdx = refLayout.getBlockIndex(instanceName.c_str()); 22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.c_str()); 22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((block.getFlags() & (LAYOUT_STD140|LAYOUT_STD430)) == 0) 22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Not std* layout. 22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(refBlockNdx >= 0); 22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpBlockNdx < 0) 22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Not found. 23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer block '" << instanceName << "' not found" << TestLog::EndMessage; 23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& refBlockLayout = refLayout.blocks[refBlockNdx]; 23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx]; 23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-01-24 pyry] Verify that activeVarIndices is correct. 23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-01-24 pyry] Verify all instances. 23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refBlockLayout.activeVarIndices.size() != cmpBlockLayout.activeVarIndices.size()) 23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Number of active variables differ in block '" << instanceName 23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "' (expected " << refBlockLayout.activeVarIndices.size() 23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", got " << cmpBlockLayout.activeVarIndices.size() 23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ")" << TestLog::EndMessage; 23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator ndxIter = refBlockLayout.activeVarIndices.begin(); ndxIter != refBlockLayout.activeVarIndices.end(); ndxIter++) 23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& refEntry = refLayout.bufferVars[*ndxIter]; 23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpEntryNdx = cmpLayout.getVariableIndex(refEntry.name.c_str()); 23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpEntryNdx < 0) 23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer variable '" << refEntry.name << "' not found" << TestLog::EndMessage; 23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& cmpEntry = cmpLayout.bufferVars[cmpEntryNdx]; 23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntry.type != cmpEntry.type || 23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.arraySize != cmpEntry.arraySize || 23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.offset != cmpEntry.offset || 23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.arrayStride != cmpEntry.arrayStride || 23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.matrixStride != cmpEntry.matrixStride || 23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.topLevelArraySize != cmpEntry.topLevelArraySize || 23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.topLevelArrayStride != cmpEntry.topLevelArrayStride || 23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.isRowMajor != cmpEntry.isRowMajor) 23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Layout mismatch in '" << refEntry.name << "':\n" 23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " expected: " << refEntry << "\n" 23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " got: " << cmpEntry 23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::compareSharedBlocks (const BufferLayout& refLayout, const BufferLayout& cmpLayout) const 23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = m_interface.getNumBlocks(); 23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = m_interface.getBlock(blockNdx); 23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isArray = block.isArray(); 23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string instanceName = string(block.getBlockName()) + (isArray ? "[0]" : ""); 23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int refBlockNdx = refLayout.getBlockIndex(instanceName.c_str()); 23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.c_str()); 23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((block.getFlags() & LAYOUT_SHARED) == 0) 23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Not shared layout. 23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(refBlockNdx >= 0); 23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpBlockNdx < 0) 23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Not found, should it? 23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer block '" << instanceName << "' not found" << TestLog::EndMessage; 23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& refBlockLayout = refLayout.blocks[refBlockNdx]; 23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx]; 23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refBlockLayout.activeVarIndices.size() != cmpBlockLayout.activeVarIndices.size()) 23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Number of active variables differ in block '" << instanceName 23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "' (expected " << refBlockLayout.activeVarIndices.size() 23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", got " << cmpBlockLayout.activeVarIndices.size() 23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ")" << TestLog::EndMessage; 23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator ndxIter = refBlockLayout.activeVarIndices.begin(); ndxIter != refBlockLayout.activeVarIndices.end(); ndxIter++) 23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& refEntry = refLayout.bufferVars[*ndxIter]; 23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpEntryNdx = cmpLayout.getVariableIndex(refEntry.name.c_str()); 23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpEntryNdx < 0) 23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer variable '" << refEntry.name << "' not found" << TestLog::EndMessage; 24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& cmpEntry = cmpLayout.bufferVars[cmpEntryNdx]; 24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntry.type != cmpEntry.type || 24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.arraySize != cmpEntry.arraySize || 24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.topLevelArraySize != cmpEntry.topLevelArraySize || 24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refEntry.isRowMajor != cmpEntry.isRowMajor) 24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Type / array size mismatch in '" << refEntry.name << "':\n" 24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " expected: " << refEntry << "\n" 24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " got: " << cmpEntry 24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::compareTypes (const BufferLayout& refLayout, const BufferLayout& cmpLayout) const 24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = m_interface.getNumBlocks(); 24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBlock& block = m_interface.getBlock(blockNdx); 24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isArray = block.isArray(); 24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = isArray ? block.getArraySize() : 1; 24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++) 24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream instanceName; 24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instanceName << block.getBlockName(); 24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isArray) 24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instanceName << "[" << instanceNdx << "]"; 24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpBlockNdx = cmpLayout.getBlockIndex(instanceName.str().c_str()); 24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpBlockNdx < 0) 24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& cmpBlockLayout = cmpLayout.blocks[cmpBlockNdx]; 24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator ndxIter = cmpBlockLayout.activeVarIndices.begin(); ndxIter != cmpBlockLayout.activeVarIndices.end(); ndxIter++) 24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& cmpEntry = cmpLayout.bufferVars[*ndxIter]; 24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int refEntryNdx = refLayout.getVariableIndex(cmpEntry.name.c_str()); 24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntryNdx < 0) 24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer variable '" << cmpEntry.name << "' not found in reference layout" << TestLog::EndMessage; 24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& refEntry = refLayout.bufferVars[refEntryNdx]; 24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntry.type != cmpEntry.type) 24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Buffer variable type mismatch in '" << refEntry.name << "':\n" 24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " expected: " << glu::getDataTypeName(refEntry.type) << "\n" 24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " got: " << glu::getDataTypeName(cmpEntry.type) 24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntry.arraySize < cmpEntry.arraySize) 24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Invalid array size in '" << refEntry.name << "': expected <= " << refEntry.arraySize << TestLog::EndMessage; 24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refEntry.topLevelArraySize < cmpEntry.topLevelArraySize) 24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Invalid top-level array size in '" << refEntry.name << "': expected <= " << refEntry.topLevelArraySize << TestLog::EndMessage; 24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::checkLayoutIndices (const BufferLayout& layout) const 24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVars = (int)layout.bufferVars.size(); 24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBlocks = (int)layout.blocks.size(); 24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check variable block indices. 25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < numVars; varNdx++) 25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& bufVar = layout.bufferVars[varNdx]; 25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (bufVar.blockNdx < 0 || !deInBounds32(bufVar.blockNdx, 0, numBlocks)) 25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Invalid block index in buffer variable '" << bufVar.name << "'" << TestLog::EndMessage; 25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check active variables. 25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& block = layout.blocks[blockNdx]; 25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<int>::const_iterator varNdxIter = block.activeVarIndices.begin(); varNdxIter != block.activeVarIndices.end(); varNdxIter++) 25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!deInBounds32(*varNdxIter, 0, numVars)) 25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Invalid active variable index " << *varNdxIter << " in block '" << block.name << "'" << TestLog::EndMessage; 25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::checkLayoutBounds (const BufferLayout& layout) const 25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVars = (int)layout.bufferVars.size(); 25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < numVars; varNdx++) 25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferVarLayoutEntry& var = layout.bufferVars[varNdx]; 25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (var.blockNdx < 0 || isUnsizedArray(var)) 25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& block = layout.blocks[var.blockNdx]; 25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(var.type); 25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVecs = isMatrix ? (var.isRowMajor ? glu::getDataTypeMatrixNumRows(var.type) : glu::getDataTypeMatrixNumColumns(var.type)) : 1; 25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numComps = isMatrix ? (var.isRowMajor ? glu::getDataTypeMatrixNumColumns(var.type) : glu::getDataTypeMatrixNumRows(var.type)) : glu::getDataTypeScalarSize(var.type); 25468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int numElements = var.arraySize; 25478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int topLevelSize = var.topLevelArraySize; 25488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int arrayStride = var.arrayStride; 25498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int topLevelStride = var.topLevelArrayStride; 25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int compSize = sizeof(deUint32); 25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int vecSize = numComps*compSize; 25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int minOffset = 0; 25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxOffset = 0; 25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // For negative strides. 25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minOffset = de::min(minOffset, (numVecs-1)*var.matrixStride); 25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minOffset = de::min(minOffset, (numElements-1)*arrayStride); 25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry minOffset = de::min(minOffset, (topLevelSize-1)*topLevelStride + (numElements-1)*arrayStride + (numVecs-1)*var.matrixStride); 25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxOffset = de::max(maxOffset, vecSize); 25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxOffset = de::max(maxOffset, (numVecs-1)*var.matrixStride + vecSize); 25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxOffset = de::max(maxOffset, (numElements-1)*arrayStride + vecSize); 25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxOffset = de::max(maxOffset, (topLevelSize-1)*topLevelStride + (numElements-1)*arrayStride + vecSize); 25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxOffset = de::max(maxOffset, (topLevelSize-1)*topLevelStride + (numElements-1)*arrayStride + (numVecs-1)*var.matrixStride + vecSize); 25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (var.offset+minOffset < 0 || var.offset+maxOffset > block.size) 25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Error: Variable '" << var.name << "' out of block bounds" << TestLog::EndMessage; 25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::checkIndexQueries (deUint32 program, const BufferLayout& layout) const 25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestLog& log = m_testCtx.getLog(); 25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderCtx.getFunctions(); 25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Spec mandates that buffer blocks are assigned consecutive locations from 0. 25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // BlockLayoutEntries are stored in that order in UniformLayout. 25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)layout.blocks.size(); blockNdx++) 25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockLayoutEntry& block = layout.blocks[blockNdx]; 25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int queriedNdx = gl.getProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, block.name.c_str()); 25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (queriedNdx != blockNdx) 25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "ERROR: glGetProgramResourceIndex(" << block.name << ") returned " << queriedNdx << ", expected " << blockNdx << "!" << TestLog::EndMessage; 25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk = false; 25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex()"); 25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool SSBOLayoutCase::execute (deUint32 program) 26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderCtx.getFunctions(); 26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 numPassedLoc = gl.getProgramResourceIndex(program, GL_UNIFORM, "ac_numPassed"); 26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceVariableInfo acVarInfo = numPassedLoc != GL_INVALID_INDEX ? glu::getProgramInterfaceVariableInfo(gl, program, GL_UNIFORM, numPassedLoc) 26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::InterfaceVariableInfo(); 26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlockInfo acBufferInfo = acVarInfo.atomicCounterBufferIndex != GL_INVALID_INDEX ? glu::getProgramInterfaceBlockInfo(gl, program, GL_ATOMIC_COUNTER_BUFFER, acVarInfo.atomicCounterBufferIndex) 26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : glu::InterfaceBlockInfo(); 26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Buffer acBuffer (m_renderCtx); 26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isOk = true; 26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numPassedLoc == GL_INVALID_INDEX) 26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("No location for ac_numPassed found"); 26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (acBufferInfo.index == GL_INVALID_INDEX) 26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("ac_numPassed buffer index is GL_INVALID_INDEX"); 26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (acBufferInfo.dataSize == 0) 26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("ac_numPassed buffer size = 0"); 26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize atomic counter buffer. 26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint8> emptyData(acBufferInfo.dataSize, 0); 26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, *acBuffer); 26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, (glw::GLsizeiptr)emptyData.size(), &emptyData[0], GL_STATIC_READ); 26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, acBufferInfo.index, *acBuffer); 26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Setting up buffer for ac_numPassed failed"); 26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(program); 26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.dispatchCompute(1, 1, 1); 26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute() failed"); 26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read back ac_numPassed data. 26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* mapPtr = gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, acBufferInfo.dataSize, GL_MAP_READ_BIT); 26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refCount = 1; 26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int resCount = 0; 26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER) failed"); 26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(mapPtr); 26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resCount = *(const int*)((const deUint8*)mapPtr + acVarInfo.offset); 26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER) failed"); 26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (refCount != resCount) 26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: ac_numPassed = " << resCount << ", expected " << refCount << TestLog::EndMessage; 26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry isOk = false; 26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Shader execution failed"); 26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return isOk; 26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 2664