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 Program interface utilities 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramInterfaceDefinitionUtil.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramInterfaceDefinition.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarTypeUtil.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set> 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map> 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace ProgramInterfaceDefinition 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableSearchFilter VariableSearchFilter::intersection (const VariableSearchFilter& a, const VariableSearchFilter& b) 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool storageNonEmpty = (a.m_storage == b.m_storage) || (a.m_storage == glu::STORAGE_LAST) || (b.m_storage == glu::STORAGE_LAST); 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool shaderTypeNonEmpty = (a.m_shaderType == b.m_shaderType) || (a.m_shaderType == glu::SHADERTYPE_LAST) || (b.m_shaderType == glu::SHADERTYPE_LAST); 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return VariableSearchFilter((a.m_shaderType == glu::SHADERTYPE_LAST) ? (b.m_shaderType) : (a.m_shaderType), 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (a.m_storage == glu::STORAGE_LAST) ? (b.m_storage) : (a.m_storage), 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !storageNonEmpty || !shaderTypeNonEmpty || a.m_null || b.m_null); 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // ProgramInterfaceDefinition 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool incrementMultiDimensionIndex (std::vector<int>& index, const std::vector<int>& dimensions) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int incrementDimensionNdx = (int)(index.size() - 1); 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (incrementDimensionNdx >= 0) 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (++index[incrementDimensionNdx] == dimensions[incrementDimensionNdx]) 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry index[incrementDimensionNdx--] = 0; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (incrementDimensionNdx != -1); 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid generateVariableTypeResourceNames (std::vector<std::string>& resources, const std::string& name, const glu::VarType& type, deUint32 resourceNameGenerationFlags) 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT((resourceNameGenerationFlags & (~RESOURCE_NAME_GENERATION_FLAG_MASK)) == 0); 7879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 7979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // remove top-level flag from children 8079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const deUint32 childFlags = resourceNameGenerationFlags & ~((deUint32)RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE); 8179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resources.push_back(name); 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::StructType* structType = type.getStructPtr(); 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < structType->getNumMembers(); ++ndx) 8879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, name + "." + structType->getMember(ndx).getName(), structType->getMember(ndx).getType(), childFlags); 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Bottom-level arrays of basic types of a transform feedback variable will produce only the first 9379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // element but without the trailing "[0]" 9479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (type.getElementType().isBasicType() && 9579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry (resourceNameGenerationFlags & RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE) != 0) 9679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 9779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry resources.push_back(name); 9879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Bottom-level arrays of basic types and SSBO top-level arrays of any type procude only first element 10079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry else if (type.getElementType().isBasicType() || 10179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry (resourceNameGenerationFlags & RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE) != 0) 10279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 10379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, name + "[0]", type.getElementType(), childFlags); 10479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 10579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Other arrays of aggregate types are expanded 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < type.getArraySize(); ++ndx) 10979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, name + "[" + de::toString(ndx) + "]", type.getElementType(), childFlags); 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Program source generation 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing ProgramInterfaceDefinition::VariablePathComponent; 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing ProgramInterfaceDefinition::VariableSearchFilter; 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* getShaderTypeDeclarations (glu::ShaderType type) 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_VERTEX: 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ""; 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_FRAGMENT: 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ""; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_GEOMETRY: 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "layout(points) in;\n" 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(points, max_vertices=3) out;\n"; 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_TESSELLATION_CONTROL: 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "layout(vertices=1) out;\n"; 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_TESSELLATION_EVALUATION: 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "layout(triangle, point_mode) in;\n"; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_COMPUTE: 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "layout(local_size_x=1) in;\n"; 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass StructNameEqualPredicate 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry StructNameEqualPredicate (const char* name) : m_name(name) { } 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const glu::StructType* type) { return type->hasTypeName() && (deStringEqual(m_name, type->getTypeName()) == DE_TRUE); } 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* m_name; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void collectNamedStructureDefinitions (std::vector<const glu::StructType*>& dst, const glu::VarType& type) 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return collectNamedStructureDefinitions(dst, type.getElementType()); 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.getStructPtr()->hasTypeName()) 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // must be unique (may share the the same struct) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const glu::StructType*>::iterator where = std::find_if(dst.begin(), dst.end(), StructNameEqualPredicate(type.getStructPtr()->getTypeName())); 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (where != dst.end()) 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(**where == *type.getStructPtr()); 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // identical type has been added already, types of members must be added too 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Add types of members first 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx) 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectNamedStructureDefinitions(dst, type.getStructPtr()->getMember(ndx).getType()); 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.push_back(type.getStructPtr()); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeStructureDefinitions (std::ostringstream& buf, const ProgramInterfaceDefinition::DefaultBlock& defaultBlock) 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const glu::StructType*> namedStructs; 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Collect all structs in post order 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)defaultBlock.variables.size(); ++ndx) 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectNamedStructureDefinitions(namedStructs, defaultBlock.variables[ndx].varType); 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)defaultBlock.interfaceBlocks.size(); ++blockNdx) 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)defaultBlock.interfaceBlocks[blockNdx].variables.size(); ++ndx) 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry collectNamedStructureDefinitions(namedStructs, defaultBlock.interfaceBlocks[blockNdx].variables[ndx].varType); 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int structNdx = 0; structNdx < (int)namedStructs.size(); ++structNdx) 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "struct " << namedStructs[structNdx]->getTypeName() << "\n" 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < namedStructs[structNdx]->getNumMembers(); ++memberNdx) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << glu::indent(1) << glu::declare(namedStructs[structNdx]->getMember(memberNdx).getType(), namedStructs[structNdx]->getMember(memberNdx).getName(), 1) << ";\n"; 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "};\n"; 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!namedStructs.empty()) 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n"; 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeInterfaceBlock (std::ostringstream& buf, const glu::InterfaceBlock& interfaceBlock) 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << interfaceBlock.layout; 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interfaceBlock.layout != glu::Layout()) 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " "; 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << glu::getStorageName(interfaceBlock.storage) << " " << interfaceBlock.interfaceName << "\n" 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n"; 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)interfaceBlock.variables.size(); ++ndx) 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << glu::indent(1) << interfaceBlock.variables[ndx] << ";\n"; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}"; 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!interfaceBlock.instanceName.empty()) 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " " << interfaceBlock.instanceName; 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)interfaceBlock.dimensions.size(); ++dimensionNdx) 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "[" << interfaceBlock.dimensions[dimensionNdx] << "]"; 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ";\n\n"; 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeVariableReadAccumulateExpression (std::ostringstream& buf, const std::string& accumulatorName, const std::string& name, const glu::VarType& varType) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (varType.isBasicType()) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\t" << accumulatorName << " += "; 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeScalar(varType.getBasicType())) 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(" << name << "))"; 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeVector(varType.getBasicType())) 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(" << name << ".xyxy)"; 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeMatrix(varType.getBasicType())) 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(" << name << "[0][0]))"; 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeSamplerMultisample(varType.getBasicType())) 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(textureSize(" << name << ").x))"; 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeSampler(varType.getBasicType())) 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(textureSize(" << name << ", 0).x))"; 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeImage(varType.getBasicType())) 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(imageSize(" << name << ").x))"; 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varType.getBasicType() == glu::TYPE_UINT_ATOMIC_COUNTER) 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "vec4(float(atomicCounterIncrement(" << name << ")))"; 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ";\n"; 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varType.isStructType()) 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx) 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(buf, accumulatorName, name + "." + varType.getStructPtr()->getMember(ndx).getName(), varType.getStructPtr()->getMember(ndx).getType()); 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varType.isArrayType()) 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (varType.getArraySize() != glu::VarType::UNSIZED_ARRAY) 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < varType.getArraySize(); ++ndx) 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[" + de::toString(ndx) + "]", varType.getElementType()); 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(buf, accumulatorName, name + "[8]", varType.getElementType()); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeInterfaceReadAccumulateExpression (std::ostringstream& buf, const std::string& accumulatorName, const glu::InterfaceBlock& block) 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.dimensions.empty()) 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string prefix = (block.instanceName.empty()) ? ("") : (block.instanceName + "."); 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx) 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(buf, accumulatorName, prefix + block.variables[ndx].name, block.variables[ndx].varType); 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> index(block.dimensions.size(), 0); 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // access element 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream name; 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << block.instanceName; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)block.dimensions.size(); ++dimensionNdx) 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << index[dimensionNdx] << "]"; 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx) 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(buf, accumulatorName, name.str() + "." + block.variables[ndx].name, block.variables[ndx].varType); 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // increment index 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!incrementMultiDimensionIndex(index, block.dimensions)) 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeVariableWriteExpression (std::ostringstream& buf, const std::string& sourceVec4Name, const std::string& name, const glu::VarType& varType) 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (varType.isBasicType()) 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\t" << name << " = "; 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeScalar(varType.getBasicType())) 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << glu::getDataTypeName(varType.getBasicType()) << "(" << sourceVec4Name << ".y)"; 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeVector(varType.getBasicType()) || glu::isDataTypeMatrix(varType.getBasicType())) 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << glu::getDataTypeName(varType.getBasicType()) << "(" << glu::getDataTypeName(glu::getDataTypeScalarType(varType.getBasicType())) << "(" << sourceVec4Name << ".y))"; 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << ";\n"; 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varType.isStructType()) 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < varType.getStructPtr()->getNumMembers(); ++ndx) 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(buf, sourceVec4Name, name + "." + varType.getStructPtr()->getMember(ndx).getName(), varType.getStructPtr()->getMember(ndx).getType()); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varType.isArrayType()) 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (varType.getArraySize() != glu::VarType::UNSIZED_ARRAY) 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < varType.getArraySize(); ++ndx) 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(buf, sourceVec4Name, name + "[" + de::toString(ndx) + "]", varType.getElementType()); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(buf, sourceVec4Name, name + "[9]", varType.getElementType()); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void writeInterfaceWriteExpression (std::ostringstream& buf, const std::string& sourceVec4Name, const glu::InterfaceBlock& block) 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.dimensions.empty()) 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string prefix = (block.instanceName.empty()) ? ("") : (block.instanceName + "."); 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx) 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(buf, sourceVec4Name, prefix + block.variables[ndx].name, block.variables[ndx].varType); 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> index(block.dimensions.size(), 0); 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // access element 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream name; 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << block.instanceName; 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)block.dimensions.size(); ++dimensionNdx) 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << index[dimensionNdx] << "]"; 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx) 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(buf, sourceVec4Name, name.str() + "." + block.variables[ndx].name, block.variables[ndx].varType); 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // increment index 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!incrementMultiDimensionIndex(index, block.dimensions)) 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyrystatic bool traverseVariablePath (std::vector<VariablePathComponent>& typePath, const char* subPath, const glu::VarType& type) 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry glu::VarTokenizer tokenizer(subPath); 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.push_back(VariablePathComponent(&type)); 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tokenizer.getToken() == glu::VarTokenizer::TOKEN_END) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isStructType() && tokenizer.getToken() == glu::VarTokenizer::TOKEN_PERIOD) 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // malformed path 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_IDENTIFIER) 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < type.getStructPtr()->getNumMembers(); ++memberNdx) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.getStructPtr()->getMember(memberNdx).getName() == tokenizer.getIdentifier()) 40879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry return traverseVariablePath(typePath, subPath + tokenizer.getCurrentTokenEndLocation(), type.getStructPtr()->getMember(memberNdx).getType()); 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // malformed path, no such member 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType() && tokenizer.getToken() == glu::VarTokenizer::TOKEN_LEFT_BRACKET) 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // malformed path 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_NUMBER) 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tokenizer.getToken() != glu::VarTokenizer::TOKEN_RIGHT_BRACKET) 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry return traverseVariablePath(typePath, subPath + tokenizer.getCurrentTokenEndLocation(), type.getElementType()); 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool traverseVariablePath (std::vector<VariablePathComponent>& typePath, const std::string& path, const glu::VariableDeclaration& var) 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::parseVariableName(path.c_str()) != var.name) 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.push_back(VariablePathComponent(&var)); 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return traverseVariablePath(typePath, path.c_str() + var.name.length(), var.varType); 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool traverseShaderVariablePath (std::vector<VariablePathComponent>& typePath, const ProgramInterfaceDefinition::Shader* shader, const std::string& path, const VariableSearchFilter& filter) 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Default block variable? 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx) 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (filter.matchesFilter(shader->getDefaultBlock().variables[varNdx])) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (traverseVariablePath(typePath, path, shader->getDefaultBlock().variables[varNdx])) 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // is variable an interface block variable? 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockName = glu::parseVariableName(path.c_str()); 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!filter.matchesFilter(shader->getDefaultBlock().interfaceBlocks[interfaceNdx])) 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].interfaceName == blockName) 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // resource is a member of a named interface block 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note there is no array index specifier even if the interface is declared as an array of instances 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockMemberPath = path.substr(blockName.size() + 1); 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockMemeberName = glu::parseVariableName(blockMemberPath.c_str()); 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables.size(); ++varNdx) 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx].name == blockMemeberName) 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.push_back(VariablePathComponent(&shader->getDefaultBlock().interfaceBlocks[interfaceNdx])); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return traverseVariablePath(typePath, blockMemberPath, shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx]); 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // terminate search 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].instanceName.empty()) 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockMemeberName = glu::parseVariableName(path.c_str()); 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // unnamed block contains such variable? 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables.size(); ++varNdx) 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx].name == blockMemeberName) 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.push_back(VariablePathComponent(&shader->getDefaultBlock().interfaceBlocks[interfaceNdx])); 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return traverseVariablePath(typePath, path, shader->getDefaultBlock().interfaceBlocks[interfaceNdx].variables[varNdx]); 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // continue search 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool traverseProgramVariablePath (std::vector<VariablePathComponent>& typePath, const ProgramInterfaceDefinition::Program* program, const std::string& path, const VariableSearchFilter& filter) 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* shader = program->getShaders()[shaderNdx]; 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (filter.matchesFilter(shader)) 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note modifying output variable even when returning false 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.clear(); 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (traverseShaderVariablePath(typePath, shader, path, filter)) 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool containsSubType (const glu::VarType& complexType, glu::DataType basicType) 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (complexType.isBasicType()) 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return complexType.getBasicType() == basicType; 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isArrayType()) 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return containsSubType(complexType.getElementType(), basicType); 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isStructType()) 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < complexType.getStructPtr()->getNumMembers(); ++ndx) 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (containsSubType(complexType.getStructPtr()->getMember(ndx).getType(), basicType)) 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumShaderBlocks (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retVal = 0; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage) 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = 1; 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx) 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx]; 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += numInstances; 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumAtomicCounterBuffers (const ProgramInterfaceDefinition::Shader* shader) 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<int> buffers; 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER)) 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffers.insert(shader->getDefaultBlock().variables[ndx].layout.binding); 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)buffers.size(); 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <bool B> 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool dummyConstantTypeFilter (glu::DataType d) 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(d); 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return B; 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumTypeInstances (const glu::VarType& complexType, bool (*predicate)(glu::DataType)) 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (complexType.isBasicType()) 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (predicate(complexType.getBasicType())) 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isArrayType()) 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = (complexType.getArraySize() == glu::VarType::UNSIZED_ARRAY) ? (1) : (complexType.getArraySize()); 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return arraySize * getNumTypeInstances(complexType.getElementType(), predicate); 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isStructType()) 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int sum = 0; 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < complexType.getStructPtr()->getNumMembers(); ++ndx) 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sum += getNumTypeInstances(complexType.getStructPtr()->getMember(ndx).getType(), predicate); 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sum; 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getMappedBasicTypeSum (const glu::VarType& complexType, int (*typeMap)(glu::DataType)) 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (complexType.isBasicType()) 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return typeMap(complexType.getBasicType()); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isArrayType()) 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = (complexType.getArraySize() == glu::VarType::UNSIZED_ARRAY) ? (1) : (complexType.getArraySize()); 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return arraySize * getMappedBasicTypeSum(complexType.getElementType(), typeMap); 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (complexType.isStructType()) 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int sum = 0; 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < complexType.getStructPtr()->getNumMembers(); ++ndx) 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sum += getMappedBasicTypeSum(complexType.getStructPtr()->getMember(ndx).getType(), typeMap); 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sum; 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumTypeInstances (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage, bool (*predicate)(glu::DataType)) 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retVal = 0; 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage) 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = 1; 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx) 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx]; 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].variables.size(); ++varNdx) 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += numInstances * getNumTypeInstances(shader->getDefaultBlock().interfaceBlocks[ndx].variables[varNdx].varType, predicate); 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx) 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[varNdx].storage == storage) 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += getNumTypeInstances(shader->getDefaultBlock().variables[varNdx].varType, predicate); 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getMappedBasicTypeSum (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage, int (*typeMap)(glu::DataType)) 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retVal = 0; 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage) 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = 1; 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx) 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx]; 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].variables.size(); ++varNdx) 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += numInstances * getMappedBasicTypeSum(shader->getDefaultBlock().interfaceBlocks[ndx].variables[varNdx].varType, typeMap); 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx) 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[varNdx].storage == storage) 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += getMappedBasicTypeSum(shader->getDefaultBlock().variables[varNdx].varType, typeMap); 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumDataTypeComponents (glu::DataType type) 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeScalarOrVector(type) || glu::isDataTypeMatrix(type)) 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeScalarSize(type); 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumDataTypeVectors (glu::DataType type) 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeScalar(type)) 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeVector(type)) 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeMatrix(type)) 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeMatrixNumColumns(type); 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumComponents (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getMappedBasicTypeSum(shader, storage, getNumDataTypeComponents); 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumVectors (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getMappedBasicTypeSum(shader, storage, getNumDataTypeVectors); 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumDefaultBlockComponents (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int retVal = 0; 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varNdx = 0; varNdx < (int)shader->getDefaultBlock().variables.size(); ++varNdx) 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[varNdx].storage == storage) 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal += getMappedBasicTypeSum(shader->getDefaultBlock().variables[varNdx].varType, getNumDataTypeComponents); 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getMaxBufferBinding (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxBinding = -1; 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage) 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int binding = (shader->getDefaultBlock().interfaceBlocks[ndx].layout.binding == -1) ? (0) : (shader->getDefaultBlock().interfaceBlocks[ndx].layout.binding); 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numInstances = 1; 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)shader->getDefaultBlock().interfaceBlocks[ndx].dimensions.size(); ++dimensionNdx) 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numInstances *= shader->getDefaultBlock().interfaceBlocks[ndx].dimensions[dimensionNdx]; 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxBinding = de::max(maxBinding, binding + numInstances - 1); 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)maxBinding; 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getBufferTypeSize (glu::DataType type, glu::MatrixOrder order) 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // assume vec4 alignments, should produce values greater than or equal to the actual resource usage 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVectors = 0; 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeScalarOrVector(type)) 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVectors = 1; 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeMatrix(type) && order == glu::MATRIXORDER_ROW_MAJOR) 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVectors = glu::getDataTypeMatrixNumRows(type); 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (glu::isDataTypeMatrix(type) && order != glu::MATRIXORDER_ROW_MAJOR) 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVectors = glu::getDataTypeMatrixNumColumns(type); 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4 * numVectors; 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getBufferVariableSize (const glu::VarType& type, glu::MatrixOrder order) 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getBufferTypeSize(type.getBasicType(), order); 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = (type.getArraySize() == glu::VarType::UNSIZED_ARRAY) ? (1) : (type.getArraySize()); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return arraySize * getBufferVariableSize(type.getElementType(), order); 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int sum = 0; 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx) 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sum += getBufferVariableSize(type.getStructPtr()->getMember(ndx).getType(), order); 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sum; 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getBufferSize (const glu::InterfaceBlock& block, glu::MatrixOrder blockOrder) 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size = 0; 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)block.variables.size(); ++ndx) 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size += getBufferVariableSize(block.variables[ndx].varType, (block.variables[ndx].layout.matrixOrder == glu::MATRIXORDER_LAST) ? (blockOrder) : (block.variables[ndx].layout.matrixOrder)); 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return size; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getBufferMaxSize (const ProgramInterfaceDefinition::Shader* shader, glu::Storage storage) 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxSize = 0; 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().interfaceBlocks[ndx].storage == storage) 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxSize = de::max(maxSize, getBufferSize(shader->getDefaultBlock().interfaceBlocks[ndx], shader->getDefaultBlock().interfaceBlocks[ndx].layout.matrixOrder)); 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)maxSize; 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getAtomicCounterMaxBinding (const ProgramInterfaceDefinition::Shader* shader) 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxBinding = -1; 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER)) 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1); 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxBinding = de::max(maxBinding, shader->getDefaultBlock().variables[ndx].layout.binding); 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)maxBinding; 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getUniformMaxBinding (const ProgramInterfaceDefinition::Shader* shader, bool (*predicate)(glu::DataType)) 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxBinding = -1; 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxBinding = de::max(maxBinding, shader->getDefaultBlock().variables[ndx].layout.binding + getNumTypeInstances(shader->getDefaultBlock().variables[ndx].varType, predicate)); 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)maxBinding; 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getAtomicCounterMaxBufferSize (const ProgramInterfaceDefinition::Shader* shader) 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::map<int, int> bufferSizes; 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxSize = 0; 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (containsSubType(shader->getDefaultBlock().variables[ndx].varType, glu::TYPE_UINT_ATOMIC_COUNTER)) 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferBinding = shader->getDefaultBlock().variables[ndx].layout.binding; 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int offset = (shader->getDefaultBlock().variables[ndx].layout.offset == -1) ? (0) : (shader->getDefaultBlock().variables[ndx].layout.offset); 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int size = offset + 4 * getNumTypeInstances(shader->getDefaultBlock().variables[ndx].varType, glu::isDataTypeAtomicCounter); 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(shader->getDefaultBlock().variables[ndx].layout.binding != -1); 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (bufferSizes.find(bufferBinding) == bufferSizes.end()) 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bufferSizes[bufferBinding] = size; 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bufferSizes[bufferBinding] = de::max<int>(bufferSizes[bufferBinding], size); 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (std::map<int, int>::iterator it = bufferSizes.begin(); it != bufferSizes.end(); ++it) 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxSize = de::max<int>(maxSize, it->second); 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return maxSize; 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumFeedbackVaryingComponents (const ProgramInterfaceDefinition::Program* program, const std::string& name) 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VariablePathComponent> path; 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (name == "gl_Position") 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4; 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(deStringBeginsWith(name.c_str(), "gl_") == DE_FALSE); 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!traverseProgramVariablePath(path, program, name, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_OUT))) 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); // Program failed validate, invalid operation 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getMappedBasicTypeSum(*path.back().getVariableType(), getNumDataTypeComponents); 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumXFBComponents (const ProgramInterfaceDefinition::Program* program) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numComponents = 0; 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx) 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numComponents += getNumFeedbackVaryingComponents(program, program->getTransformFeedbackVaryings()[ndx]); 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numComponents; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumMaxXFBOutputComponents (const ProgramInterfaceDefinition::Program* program) 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numComponents = 0; 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx) 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numComponents = de::max(numComponents, getNumFeedbackVaryingComponents(program, program->getTransformFeedbackVaryings()[ndx])); 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numComponents; 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8969fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyrystatic int getFragmentOutputMaxLocation (const ProgramInterfaceDefinition::Shader* shader) 8979fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry{ 8989fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry DE_ASSERT(shader->getType() == glu::SHADERTYPE_FRAGMENT); 8999fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9009fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry int maxOutputLocation = -1; 9019fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9029fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 9039fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry { 9049fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_OUT) 9059fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry { 9069fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry // missing location qualifier means location == 0 9079fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry const int outputLocation = (shader->getDefaultBlock().variables[ndx].layout.location == -1) 9089fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry ? (0) 9099fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry : (shader->getDefaultBlock().variables[ndx].layout.location); 9109fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9119fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry // only basic types or arrays of basic types possible 9129fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry DE_ASSERT(!shader->getDefaultBlock().variables[ndx].varType.isStructType()); 9139fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9149fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry const int locationSlotsTaken = (shader->getDefaultBlock().variables[ndx].varType.isArrayType()) 9159fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry ? (shader->getDefaultBlock().variables[ndx].varType.getArraySize()) 9169fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry : (1); 9179fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9189fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry maxOutputLocation = de::max(maxOutputLocation, outputLocation + locationSlotsTaken - 1); 9199fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry } 9209fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry } 9219fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9229fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry return maxOutputLocation; 9239fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry} 9249fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::vector<std::string> getProgramInterfaceBlockMemberResourceList (const glu::InterfaceBlock& interfaceBlock) 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string namePrefix = (!interfaceBlock.instanceName.empty()) ? (interfaceBlock.interfaceName + ".") : (""); 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isTopLevelBufferVariable = (interfaceBlock.storage == glu::STORAGE_BUFFER); 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::string> resources; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int variableNdx = 0; variableNdx < (int)interfaceBlock.variables.size(); ++variableNdx) 93479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, 93579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry namePrefix + interfaceBlock.variables[variableNdx].name, 93679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry interfaceBlock.variables[variableNdx].varType, 93779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry (isTopLevelBufferVariable) ? 93879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry (RESOURCE_NAME_GENERATION_FLAG_TOP_LEVEL_BUFFER_VARIABLE) : 93979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry (RESOURCE_NAME_GENERATION_FLAG_DEFAULT)); 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return resources; 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::vector<std::string> getProgramInterfaceResourceList (const ProgramInterfaceDefinition::Program* program, ProgramInterface interface) 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // The same {uniform (block), buffer (variable)} can exist in multiple shaders, remove duplicates but keep order 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool removeDuplicated = (interface == PROGRAMINTERFACE_UNIFORM) || 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (interface == PROGRAMINTERFACE_UNIFORM_BLOCK) || 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (interface == PROGRAMINTERFACE_BUFFER_VARIABLE) || 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (interface == PROGRAMINTERFACE_SHADER_STORAGE_BLOCK); 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::string> resources; 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (interface) 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM: 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_BUFFER_VARIABLE: 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (interface == PROGRAMINTERFACE_UNIFORM) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER); 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* shader = program->getShaders()[shaderNdx]; 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int variableNdx = 0; variableNdx < (int)shader->getDefaultBlock().variables.size(); ++variableNdx) 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[variableNdx].storage == storage) 96679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, 96779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry shader->getDefaultBlock().variables[variableNdx].name, 96879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry shader->getDefaultBlock().variables[variableNdx].varType, 96979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry RESOURCE_NAME_GENERATION_FLAG_DEFAULT); 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx]; 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interfaceBlock.storage == storage) 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<std::string> blockResources = getProgramInterfaceBlockMemberResourceList(interfaceBlock); 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resources.insert(resources.end(), blockResources.begin(), blockResources.end()); 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM_BLOCK: 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK: 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER); 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* shader = program->getShaders()[shaderNdx]; 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx]; 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interfaceBlock.storage == storage) 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> index(interfaceBlock.dimensions.size(), 0); 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // add resource string for each element 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream name; 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << interfaceBlock.interfaceName; 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)interfaceBlock.dimensions.size(); ++dimensionNdx) 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry name << "[" << index[dimensionNdx] << "]"; 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resources.push_back(name.str()); 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // increment index 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!incrementMultiDimensionIndex(index, interfaceBlock.dimensions)) 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_INPUT: 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_OUTPUT: 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (glu::STORAGE_IN) : (glu::STORAGE_OUT); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ShaderType shaderType = (interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (program->getFirstStage()) : (program->getLastStage()); 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* shader = program->getShaders()[shaderNdx]; 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() != shaderType) 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int variableNdx = 0; variableNdx < (int)shader->getDefaultBlock().variables.size(); ++variableNdx) 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[variableNdx].storage == storage) 103779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, 103879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry shader->getDefaultBlock().variables[variableNdx].name, 103979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry shader->getDefaultBlock().variables[variableNdx].varType, 104079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry RESOURCE_NAME_GENERATION_FLAG_DEFAULT); 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& interfaceBlock = shader->getDefaultBlock().interfaceBlocks[interfaceNdx]; 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interfaceBlock.storage == storage) 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<std::string> blockResources = getProgramInterfaceBlockMemberResourceList(interfaceBlock); 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resources.insert(resources.end(), blockResources.begin(), blockResources.end()); 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // built-ins 10548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (interface == PROGRAMINTERFACE_PROGRAM_INPUT) 10558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 10568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (shaderType == glu::SHADERTYPE_VERTEX && resources.empty()) 10578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_VertexID"); // only read from when there are no other inputs 10588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_FRAGMENT && resources.empty()) 10598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_FragCoord"); // only read from when there are no other inputs 10608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_GEOMETRY && resources.empty()) 10618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_in[0].gl_Position"); 10628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) 10638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 10648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const bool noInputs = resources.empty(); 10658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_InvocationID"); 10668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 10678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (noInputs) 10688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_in[0].gl_Position"); // only read from when there are no other inputs 10698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 10708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION && resources.empty()) 10718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_in[0].gl_Position"); // only read from when there are no other inputs 10728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_COMPUTE && resources.empty()) 10738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_NumWorkGroups"); // only read from when there are no other inputs 10748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 10758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (interface == PROGRAMINTERFACE_PROGRAM_OUTPUT) 10768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 10778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (shaderType == glu::SHADERTYPE_VERTEX) 10788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_Position"); 10798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_FRAGMENT && resources.empty()) 10808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_FragDepth"); // only written to when there are no other outputs 10818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_GEOMETRY) 10828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_Position"); 10838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL) 10848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_out[0].gl_Position"); 10858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else if (shaderType == glu::SHADERTYPE_TESSELLATION_EVALUATION) 10868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resources.push_back("gl_Position"); 10878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 10888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING: 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varyingNdx = 0; varyingNdx < (int)program->getTransformFeedbackVaryings().size(); ++varyingNdx) 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 109679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const std::string& varyingName = program->getTransformFeedbackVaryings()[varyingNdx]; 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deStringBeginsWith(varyingName.c_str(), "gl_")) 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resources.push_back(varyingName); // builtin 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 110179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 110279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry std::vector<VariablePathComponent> path; 110379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 110479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (!traverseProgramVariablePath(path, program, varyingName, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_OUT))) 110579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(false); // Program failed validate, invalid operation 110679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 110779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, 110879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry varyingName, 110979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry *path.back().getVariableType(), 111079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE); 111179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (removeDuplicated) 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::set<std::string> addedVariables; 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::string> uniqueResouces; 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)resources.size(); ++ndx) 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (addedVariables.find(resources[ndx]) == addedVariables.end()) 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addedVariables.insert(resources[ndx]); 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uniqueResouces.push_back(resources[ndx]); 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uniqueResouces.swap(resources); 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return resources; 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglu::ProgramSources generateProgramInterfaceProgramSources (const ProgramInterfaceDefinition::Program* program) 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(program->isValid()); 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* shader = program->getShaders()[shaderNdx]; 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool containsUserDefinedOutputs = false; 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool containsUserDefinedInputs = false; 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream sourceBuf; 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream usageBuf; 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sourceBuf << glu::getGLSLVersionDeclaration(shader->getVersion()) << "\n" 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << getShaderTypeDeclarations(shader->getType()) 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n"; 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Struct definitions 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeStructureDefinitions(sourceBuf, shader->getDefaultBlock()); 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // variables in the default scope 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sourceBuf << shader->getDefaultBlock().variables[ndx] << ";\n"; 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!shader->getDefaultBlock().variables.empty()) 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sourceBuf << "\n"; 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Interface blocks 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++ndx) 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeInterfaceBlock(sourceBuf, shader->getDefaultBlock().interfaceBlocks[ndx]); 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Use inputs and outputs so that they won't be removed by the optimizer 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << "highp vec4 readInputs()\n" 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec4 retValue = vec4(0.0);\n"; 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // User-defined inputs 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_IN || 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_UNIFORM) 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableReadAccumulateExpression(usageBuf, "retValue", shader->getDefaultBlock().variables[ndx].name, shader->getDefaultBlock().variables[ndx].varType); 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry containsUserDefinedInputs = true; 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& interface = shader->getDefaultBlock().interfaceBlocks[interfaceNdx]; 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interface.storage == glu::STORAGE_UNIFORM || 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (interface.storage == glu::STORAGE_BUFFER && (interface.memoryAccessQualifierFlags & glu::MEMORYACCESSQUALIFIER_WRITEONLY_BIT) == 0)) 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeInterfaceReadAccumulateExpression(usageBuf, "retValue", interface); 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry containsUserDefinedInputs = true; 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Built-in-inputs 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!containsUserDefinedInputs) 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_VERTEX) 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += vec4(float(gl_VertexID));\n"; 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_FRAGMENT) 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += gl_FragCoord;\n"; 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_GEOMETRY) 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += gl_in[0].gl_Position;\n"; 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_CONTROL) 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += gl_in[0].gl_Position;\n"; 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_EVALUATION) 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += gl_in[0].gl_Position;\n"; 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_COMPUTE) 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " retValue += vec4(float(gl_NumWorkGroups.x));\n"; 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " return retValue;\n" 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n\n"; 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << "void writeOutputs(in highp vec4 dummyValue)\n" 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // User-defined outputs 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)shader->getDefaultBlock().variables.size(); ++ndx) 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getDefaultBlock().variables[ndx].storage == glu::STORAGE_OUT) 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeVariableWriteExpression(usageBuf, "dummyValue", shader->getDefaultBlock().variables[ndx].name, shader->getDefaultBlock().variables[ndx].varType); 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry containsUserDefinedOutputs = true; 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int interfaceNdx = 0; interfaceNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++interfaceNdx) 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& interface = shader->getDefaultBlock().interfaceBlocks[interfaceNdx]; 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (interface.storage == glu::STORAGE_BUFFER && (interface.memoryAccessQualifierFlags & glu::MEMORYACCESSQUALIFIER_READONLY_BIT) == 0) 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeInterfaceWriteExpression(usageBuf, "dummyValue", interface); 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry containsUserDefinedOutputs = true; 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Builtin-outputs that must be written to 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_VERTEX) 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " gl_Position = dummyValue;\n"; 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_GEOMETRY) 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " gl_Position = dummyValue;\n" 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n"; 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_CONTROL) 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " gl_out[gl_InvocationID].gl_Position = dummyValue;\n"; 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_TESSELLATION_EVALUATION) 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " gl_Position = dummyValue;\n"; 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Output to sink input data to 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!containsUserDefinedOutputs) 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_FRAGMENT) 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " gl_FragDepth = dot(dummyValue.xy, dummyValue.xw);\n"; 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (shader->getType() == glu::SHADERTYPE_COMPUTE) 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << " dummyOutputBlock.dummyValue = dummyValue;\n"; 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry usageBuf << "}\n\n" 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " writeOutputs(readInputs());\n" 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Interface for dummy output 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_COMPUTE && !containsUserDefinedOutputs) 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sourceBuf << "writeonly buffer DummyOutputInterface\n" 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " highp vec4 dummyValue;\n" 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "} dummyOutputBlock;\n\n"; 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::ShaderSource(shader->getType(), sourceBuf.str() + usageBuf.str()); 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (program->isSeparable()) 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::ProgramSeparable(true); 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)program->getTransformFeedbackVaryings().size(); ++ndx) 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TransformFeedbackVarying(program->getTransformFeedbackVaryings()[ndx]); 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (program->getTransformFeedbackMode()) 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TransformFeedbackMode(program->getTransformFeedbackMode()); 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sources; 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool findProgramVariablePathByPathName (std::vector<VariablePathComponent>& typePath, const ProgramInterfaceDefinition::Program* program, const std::string& pathName, const VariableSearchFilter& filter) 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VariablePathComponent> modifiedPath; 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!traverseProgramVariablePath(modifiedPath, program, pathName, filter)) 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // modify param only on success 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typePath.swap(modifiedPath); 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterfaceDefinition::ShaderResourceUsage getShaderResourceUsage (const ProgramInterfaceDefinition::Shader* shader) 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ProgramInterfaceDefinition::ShaderResourceUsage retVal; 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numInputs = getNumTypeInstances(shader, glu::STORAGE_IN, dummyConstantTypeFilter<true>); 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numInputVectors = getNumVectors(shader, glu::STORAGE_IN); 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numInputComponents = getNumComponents(shader, glu::STORAGE_IN); 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numOutputs = getNumTypeInstances(shader, glu::STORAGE_OUT, dummyConstantTypeFilter<true>); 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numOutputVectors = getNumVectors(shader, glu::STORAGE_OUT); 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numOutputComponents = getNumComponents(shader, glu::STORAGE_OUT); 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numDefaultBlockUniformComponents = getNumDefaultBlockComponents(shader, glu::STORAGE_UNIFORM); 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedUniformComponents = getNumComponents(shader, glu::STORAGE_UNIFORM); 13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numUniformVectors = getNumVectors(shader, glu::STORAGE_UNIFORM); 13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numSamplers = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeSampler); 13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numImages = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage); 13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounterBuffers = getNumAtomicCounterBuffers(shader); 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounters = getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeAtomicCounter); 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numUniformBlocks = getNumShaderBlocks(shader, glu::STORAGE_UNIFORM); 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numShaderStorageBlocks = getNumShaderBlocks(shader, glu::STORAGE_BUFFER); 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterfaceDefinition::ProgramResourceUsage getCombinedProgramResourceUsage (const ProgramInterfaceDefinition::Program* program) 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ProgramInterfaceDefinition::ProgramResourceUsage retVal; 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13479fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.uniformBufferMaxBinding = -1; // max binding is inclusive upper bound. Allow 0 bindings by using negative value 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.uniformBufferMaxSize = 0; 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numUniformBlocks = 0; 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedVertexUniformComponents = 0; 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedFragmentUniformComponents = 0; 13529fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.shaderStorageBufferMaxBinding = -1; // see above 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.shaderStorageBufferMaxSize = 0; 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numShaderStorageBlocks = 0; 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numVaryingComponents = 0; 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numVaryingVectors = 0; 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedSamplers = 0; 13589fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.atomicCounterBufferMaxBinding = -1; // see above 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.atomicCounterBufferMaxSize = 0; 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounterBuffers = 0; 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounters = 0; 13629fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.maxImageBinding = -1; // see above 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedImages = 0; 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedOutputResources = 0; 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBInterleavedComponents = 0; 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBSeparateAttribs = 0; 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBSeparateComponents = 0; 13689fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.fragmentOutputMaxBinding = -1; // see above 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx]; 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.uniformBufferMaxBinding = de::max(retVal.uniformBufferMaxBinding, getMaxBufferBinding(shader, glu::STORAGE_UNIFORM)); 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.uniformBufferMaxSize = de::max(retVal.uniformBufferMaxSize, getBufferMaxSize(shader, glu::STORAGE_UNIFORM)); 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numUniformBlocks += getNumShaderBlocks(shader, glu::STORAGE_UNIFORM); 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_VERTEX) 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedVertexUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM); 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_FRAGMENT) 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedFragmentUniformComponents += getNumComponents(shader, glu::STORAGE_UNIFORM); 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.shaderStorageBufferMaxBinding = de::max(retVal.shaderStorageBufferMaxBinding, getMaxBufferBinding(shader, glu::STORAGE_BUFFER)); 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.shaderStorageBufferMaxSize = de::max(retVal.shaderStorageBufferMaxSize, getBufferMaxSize(shader, glu::STORAGE_BUFFER)); 13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numShaderStorageBlocks += getNumShaderBlocks(shader, glu::STORAGE_BUFFER); 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_VERTEX) 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numVaryingComponents += getNumComponents(shader, glu::STORAGE_OUT); 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numVaryingVectors += getNumVectors(shader, glu::STORAGE_OUT); 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedSamplers += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeSampler); 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.atomicCounterBufferMaxBinding = de::max(retVal.atomicCounterBufferMaxBinding, getAtomicCounterMaxBinding(shader)); 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.atomicCounterBufferMaxSize = de::max(retVal.atomicCounterBufferMaxSize, getAtomicCounterMaxBufferSize(shader)); 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounterBuffers += getNumAtomicCounterBuffers(shader); 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numAtomicCounters += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeAtomicCounter); 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.maxImageBinding = de::max(retVal.maxImageBinding, getUniformMaxBinding(shader, glu::isDataTypeImage)); 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedImages += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage); 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedOutputResources += getNumTypeInstances(shader, glu::STORAGE_UNIFORM, glu::isDataTypeImage); 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedOutputResources += getNumShaderBlocks(shader, glu::STORAGE_BUFFER); 14059fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (shader->getType() == glu::SHADERTYPE_FRAGMENT) 14079fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry { 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numCombinedOutputResources += getNumVectors(shader, glu::STORAGE_OUT); 14099fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry retVal.fragmentOutputMaxBinding = de::max(retVal.fragmentOutputMaxBinding, getFragmentOutputMaxLocation(shader)); 14109fa944ae1829441ef58596701ddc9c3d07b50f04Jarkko Pöyry } 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (program->getTransformFeedbackMode() == GL_INTERLEAVED_ATTRIBS) 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBInterleavedComponents = getNumXFBComponents(program); 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (program->getTransformFeedbackMode() == GL_SEPARATE_ATTRIBS) 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBSeparateAttribs = (int)program->getTransformFeedbackVaryings().size(); 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry retVal.numXFBSeparateComponents = getNumMaxXFBOutputComponents(program); 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return retVal; 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 1427