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 query test case 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramInterfaceQueryTestCase.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fProgramInterfaceDefinitionUtil.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarTypeUtil.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSTLUtil.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing ProgramInterfaceDefinition::VariablePathComponent; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing ProgramInterfaceDefinition::VariableSearchFilter; 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool stringEndsWith (const std::string& str, const std::string& suffix) 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (suffix.length() > str.length()) 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return str.substr(str.length() - suffix.length()) == suffix; 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glw::GLenum getProgramDefaultBlockInterfaceFromStorage (glu::Storage storage) 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (storage) 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::STORAGE_IN: return GL_PROGRAM_INPUT; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::STORAGE_OUT: return GL_PROGRAM_OUTPUT; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::STORAGE_UNIFORM: return GL_UNIFORM; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isBufferBackedInterfaceBlockStorage (glu::Storage storage) 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return storage == glu::STORAGE_BUFFER || storage == glu::STORAGE_UNIFORM; 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getTypeSize (glu::DataType type) 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type == glu::TYPE_FLOAT) 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4; 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type == glu::TYPE_INT || type == glu::TYPE_UINT) 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4; 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type == glu::TYPE_BOOL) 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4; // uint 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getVarTypeSize (const glu::VarType& type) 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // return in basic machine units 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeScalarSize(type.getBasicType()) * getTypeSize(glu::getDataTypeScalarType(type.getBasicType())); 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size = 0; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size += getVarTypeSize(type.getStructPtr()->getMember(ndx).getType()); 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return size; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // unsized arrays are handled as if they had only one element 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.getArraySize() == glu::VarType::UNSIZED_ARRAY) 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getVarTypeSize(type.getElementType()); 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return type.getArraySize() * getVarTypeSize(type.getElementType()); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::MatrixOrder getMatrixOrderFromPath (const std::vector<VariablePathComponent>& path) 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::MatrixOrder order = glu::MATRIXORDER_LAST; 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // inherit majority 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int pathNdx = 0; pathNdx < (int)path.size(); ++pathNdx) 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::MatrixOrder matOrder; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (path[pathNdx].isInterfaceBlock()) 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry matOrder = path[pathNdx].getInterfaceBlock()->layout.matrixOrder; 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[pathNdx].isDeclaration()) 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry matOrder = path[pathNdx].getDeclaration()->layout.matrixOrder; 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[pathNdx].isVariableType()) 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry matOrder = glu::MATRIXORDER_LAST; 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::MATRIXORDER_LAST; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (matOrder != glu::MATRIXORDER_LAST) 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry order = matOrder; 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return order; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PropValidator 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PropValidator (Context& context, ProgramResourcePropFlags validationProp, const char* requiredExtension = ""); 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual std::string getHumanReadablePropertyString (glw::GLint propVal) const; 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const = 0; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isSupported (void) const; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isSelected (deUint32 caseFlags) const; 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void setError (const std::string& err) const; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestContext& m_testCtx; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::RenderContext& m_renderContext; 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ContextInfo& m_contextInfo; 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string m_extension; 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramResourcePropFlags m_validationProp; 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1683c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPropValidator::PropValidator (Context& context, ProgramResourcePropFlags validationProp, const char* requiredExtension) 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_testCtx (context.getTestContext()) 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_renderContext (context.getRenderContext()) 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_contextInfo (context.getContextInfo()) 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_extension (requiredExtension) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_validationProp (validationProp) 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PropValidator::getHumanReadablePropertyString (glw::GLint propVal) const 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toString(propVal); 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool PropValidator::isSupported (void) const 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_extension.empty() || m_contextInfo.isExtensionSupported(m_extension.c_str()); 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool PropValidator::isSelected (deUint32 caseFlags) const 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (caseFlags & (deUint32)m_validationProp) != 0; 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PropValidator::setError (const std::string& err) const 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // don't overwrite earlier errors 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, err.c_str()); 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SingleVariableValidator : public PropValidator 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SingleVariableValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension = ""); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const; 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const = 0; 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter m_filter; 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLuint m_programID; 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySingleVariableValidator::SingleVariableValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PropValidator (context, validationProp, requiredExtension) 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_filter (filter) 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_programID (programID) 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SingleVariableValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VariablePathComponent> path; 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (findProgramVariablePathByPathName(path, program, resource, m_filter)) 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType* variable = (path.back().isVariableType()) ? (path.back().getVariableType()) : (DE_NULL); 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!variable || !variable->isBasicType()) 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Error, resource name \"" << resource << "\" refers to a non-basic type." << tcu::TestLog::EndMessage; 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource not basic type"); 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validateSingleVariable(path, resource, propValue); 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // finding matching variable in any shader is sufficient 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (deStringBeginsWith(resource.c_str(), "gl_")) 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // special case for builtins 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validateBuiltinVariable(resource, propValue); 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find resource \"" << resource << "\" in the program" << tcu::TestLog::EndMessage; 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("could not find resource"); 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SingleVariableValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(propValue); 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find builtin resource \"" << resource << "\" in the program" << tcu::TestLog::EndMessage; 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("could not find builtin resource"); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SingleBlockValidator : public PropValidator 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SingleBlockValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension = ""); 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const; 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual void validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue) const = 0; 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter m_filter; 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLuint m_programID; 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2713c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySingleBlockValidator::SingleBlockValidator (Context& context, ProgramResourcePropFlags validationProp, glw::GLuint programID, const VariableSearchFilter& filter, const char* requiredExtension) 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PropValidator (context, validationProp, requiredExtension) 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_filter (filter) 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_programID (programID) 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SingleBlockValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::VarTokenizer tokenizer (resource.c_str()); 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockName = tokenizer.getIdentifier(); 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<int> instanceIndex; 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // array index 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (tokenizer.getToken() == glu::VarTokenizer::TOKEN_LEFT_BRACKET) 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_NUMBER); 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry instanceIndex.push_back(tokenizer.getNumber()); 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_RIGHT_BRACKET); 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tokenizer.advance(); 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // no trailing garbage 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tokenizer.getToken() == glu::VarTokenizer::TOKEN_END); 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx]; 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_filter.matchesFilter(shader)) 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx) 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx]; 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_filter.matchesFilter(block) && block.interfaceName == blockName) 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // dimensions match 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(instanceIndex.size() == block.dimensions.size()); 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validateSingleBlock(block, instanceIndex, resource, propValue); 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Error, could not find resource \"" << resource << "\" in the program" << tcu::TestLog::EndMessage; 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("could not find resource"); 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TypeValidator : public SingleVariableValidator 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TypeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getHumanReadablePropertyString (glw::GLint propVal) const; 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3373c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTypeValidator::TypeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TYPE, programID, filter) 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string TypeValidator::getHumanReadablePropertyString (glw::GLint propVal) const 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toString(glu::getShaderVarTypeStr(propVal)); 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TypeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType* variable = path.back().getVariableType(); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(variable->getBasicType()) << tcu::TestLog::EndMessage; 3548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (variable->getBasicType() != glu::getDataTypeFromGLType(propValue)) 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage; 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource type invalid"); 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TypeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry static const struct 3658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const char* name; 3678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry glu::DataType type; 3688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } builtins[] = 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_Position", glu::TYPE_FLOAT_VEC4 }, 3718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_FragCoord", glu::TYPE_FLOAT_VEC4 }, 3728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_in[0].gl_Position", glu::TYPE_FLOAT_VEC4 }, 3738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_VertexID", glu::TYPE_INT }, 3748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_InvocationID", glu::TYPE_INT }, 3758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_NumWorkGroups", glu::TYPE_UINT_VEC3 }, 3768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { "gl_FragDepth", glu::TYPE_FLOAT }, 3778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry }; 3788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(builtins); ++ndx) 3808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (resource == builtins[ndx].name) 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(builtins[ndx].type) << tcu::TestLog::EndMessage; 3848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (glu::getDataTypeFromGLType(propValue) != builtins[ndx].type) 3868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 3878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage; 3888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry setError("resource type invalid"); 3898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 3908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry return; 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 3948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(false); 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ArraySizeValidator : public SingleVariableValidator 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ArraySizeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 4028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryArraySizeValidator::ArraySizeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ARRAY_SIZE, programID, filter) 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent nullComponent; 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& enclosingcomponent = (path.size() > 1) ? (path[path.size()-2]) : (nullComponent); 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType(); 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool inUnsizedArray = isArray && (enclosingcomponent.getVariableType()->getArraySize() == glu::VarType::UNSIZED_ARRAY); 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arraySize = (!isArray) ? (1) : (inUnsizedArray) ? (0) : (enclosingcomponent.getVariableType()->getArraySize()); 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage; 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (arraySize != propValue) 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource array size invalid"); 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid ArraySizeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 4318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 4328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // support all built-ins that getProgramInterfaceResourceList supports 4338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (resource == "gl_Position" || 4348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_VertexID" || 4358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_FragCoord" || 4368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_in[0].gl_Position" || 4378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_InvocationID" || 4388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_NumWorkGroups" || 4398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry resource == "gl_FragDepth") 4408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 4418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting 1" << tcu::TestLog::EndMessage; 4428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (propValue != 1) 4448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 4458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 4468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry setError("resource array size invalid"); 4478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 4498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry else 4508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_ASSERT(false); 4518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 4528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ArrayStrideValidator : public SingleVariableValidator 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4603c827367444ee418f129b2c238299f49d3264554Jarkko PoyryArrayStrideValidator::ArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ARRAY_STRIDE, programID, filter) 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ArrayStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent nullComponent; 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& component = path.back(); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& enclosingcomponent = (path.size() > 1) ? (path[path.size()-2]) : (nullComponent); 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& firstComponent = path.front(); 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isBufferBlock = firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage); 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType(); 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isAtomicCounter = glu::isDataTypeAtomicCounter(component.getVariableType()->getBasicType()); // atomic counters are buffer backed with a stride of 4 basic machine units 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Layout tests will verify layouts of buffer backed arrays properly. Here we just check values are greater or equal to the element size 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isBufferBlock && isArray) 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elementSize = glu::getDataTypeScalarSize(component.getVariableType()->getBasicType()) * getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType())); 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting greater or equal to " << elementSize << tcu::TestLog::EndMessage; 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue < elementSize) 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource array stride invalid"); 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Atomics are buffer backed with stride of 4 even though they are not in an interface block 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int arrayStride = (isAtomicCounter && isArray) ? (4) : (!isBufferBlock && !isAtomicCounter) ? (-1) : (0); 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array stride, expecting " << arrayStride << tcu::TestLog::EndMessage; 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (arrayStride != propValue) 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource array stride invalid"); 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BlockIndexValidator : public SingleVariableValidator 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockIndexValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockIndexValidator::BlockIndexValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_BLOCK_INDEX, programID, filter) 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockIndexValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& firstComponent = path.front(); 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!firstComponent.isInterfaceBlock()) 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting -1" << tcu::TestLog::EndMessage; 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != -1) 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource block index invalid"); 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block index, expecting a valid block index" << tcu::TestLog::EndMessage; 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue == -1) 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource block index invalid"); 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderContext.getFunctions(); 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLenum interface = (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_UNIFORM) ? (GL_UNIFORM_BLOCK) : 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (firstComponent.getInterfaceBlock()->storage == glu::STORAGE_BUFFER) ? (GL_SHADER_STORAGE_BLOCK) : 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (0); 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLint written = 0; 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<char> nameBuffer (firstComponent.getInterfaceBlock()->interfaceName.size() + 3 * firstComponent.getInterfaceBlock()->dimensions.size() + 2, '\0'); // +3 for appended "[N]", +1 for '\0' and +1 just for safety 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceName(m_programID, interface, propValue, (int)nameBuffer.size() - 1, &written, &nameBuffer[0]); 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query block name"); 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(written < (int)nameBuffer.size()); 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(nameBuffer.back() == '\0'); 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockName (&nameBuffer[0], written); 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream expectedName; 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectedName << firstComponent.getInterfaceBlock()->interfaceName; 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = 0; dimensionNdx < (int)firstComponent.getInterfaceBlock()->dimensions.size(); ++dimensionNdx) 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectedName << "[0]"; 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Block name with index " << propValue << " is \"" << blockName << "\"" << tcu::TestLog::EndMessage; 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (blockName != expectedName.str()) 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, expected " << expectedName.str() << tcu::TestLog::EndMessage; 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource block index invalid"); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsRowMajorValidator : public SingleVariableValidator 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsRowMajorValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getHumanReadablePropertyString (glw::GLint propVal) const; 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIsRowMajorValidator::IsRowMajorValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_ROW_MAJOR, programID, filter) 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IsRowMajorValidator::getHumanReadablePropertyString (glw::GLint propVal) const 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toString(glu::getBooleanStr(propVal)); 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IsRowMajorValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& component = path.back(); 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& firstComponent = path.front(); 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isBufferBlock = firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(component.getVariableType()->getBasicType()); 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int expected = (isBufferBlock && isMatrix && getMatrixOrderFromPath(path) == glu::MATRIXORDER_ROW_MAJOR) ? (1) : (0); 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix order, expecting IS_ROW_MAJOR = " << expected << tcu::TestLog::EndMessage; 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != expected) 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource matrix order invalid"); 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MatrixStrideValidator : public SingleVariableValidator 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MatrixStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMatrixStrideValidator::MatrixStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_MATRIX_STRIDE, programID, filter) 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid MatrixStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& component = path.back(); 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& firstComponent = path.front(); 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isBufferBlock = firstComponent.isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(firstComponent.getInterfaceBlock()->storage); 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMatrix = glu::isDataTypeMatrix(component.getVariableType()->getBasicType()); 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Layout tests will verify layouts of buffer backed arrays properly. Here we just check the stride is is greater or equal to the row/column size 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isBufferBlock && isMatrix) 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool columnMajor = getMatrixOrderFromPath(path) != glu::MATRIXORDER_ROW_MAJOR; 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMajorElements = (columnMajor) ? (glu::getDataTypeMatrixNumRows(component.getVariableType()->getBasicType())) : (glu::getDataTypeMatrixNumColumns(component.getVariableType()->getBasicType())); 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int majorSize = numMajorElements * getTypeSize(glu::getDataTypeScalarType(component.getVariableType()->getBasicType())); 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting greater or equal to " << majorSize << tcu::TestLog::EndMessage; 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue < majorSize) 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource matrix stride invalid"); 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int matrixStride = (!isBufferBlock && !glu::isDataTypeAtomicCounter(component.getVariableType()->getBasicType())) ? (-1) : (0); 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying matrix stride, expecting " << matrixStride << tcu::TestLog::EndMessage; 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (matrixStride != propValue) 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource matrix stride invalid"); 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AtomicCounterBufferIndexVerifier : public SingleVariableValidator 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry AtomicCounterBufferIndexVerifier (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryAtomicCounterBufferIndexVerifier::AtomicCounterBufferIndexVerifier (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_ATOMIC_COUNTER_BUFFER_INDEX, programID, filter) 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid AtomicCounterBufferIndexVerifier::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType())) 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting -1" << tcu::TestLog::EndMessage; 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != -1) 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource atomic counter buffer index invalid"); 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying atomic counter buffer index, expecting a valid index" << tcu::TestLog::EndMessage; 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue == -1) 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource atomic counter buffer index invalid"); 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderContext.getFunctions(); 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLint numActiveResources = 0; 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramInterfaceiv(m_programID, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &numActiveResources); 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramInterfaceiv(..., GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, ...)"); 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue >= numActiveResources) 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << ", GL_ACTIVE_RESOURCES = " << numActiveResources << tcu::TestLog::EndMessage; 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource atomic counter buffer index invalid"); 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LocationValidator : public SingleVariableValidator 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LocationValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 7228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryLocationValidator::LocationValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_LOCATION, programID, filter) 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getVariableLocationLength (const glu::VarType& type) 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glu::isDataTypeMatrix(type.getBasicType())) 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::getDataTypeMatrixNumColumns(type.getBasicType()); 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int size = 0; 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < type.getStructPtr()->getNumMembers(); ++ndx) 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry size += getVariableLocationLength(type.getStructPtr()->getMember(ndx).getType()); 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return size; 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return type.getArraySize() * getVariableLocationLength(type.getElementType()); 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getIOSubVariableLocation (const std::vector<VariablePathComponent>& path, int startNdx, int currentLocation) 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentLocation == -1) 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (path[startNdx].getVariableType()->isBasicType()) 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return currentLocation; 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[startNdx].getVariableType()->isArrayType()) 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getIOSubVariableLocation(path, startNdx+1, currentLocation); 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[startNdx].getVariableType()->isStructType()) 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < path[startNdx].getVariableType()->getStructPtr()->getNumMembers(); ++ndx) 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (&path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType() == path[startNdx + 1].getVariableType()) 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getIOSubVariableLocation(path, startNdx + 1, currentLocation); 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentLocation != -1) 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentLocation += getVariableLocationLength(path[startNdx].getVariableType()->getStructPtr()->getMember(ndx).getType()); 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // could not find member, never happens 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getIOBlockVariableLocation (const std::vector<VariablePathComponent>& path) 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock* block = path.front().getInterfaceBlock(); 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int currentLocation = block->layout.location; 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find the block member 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < (int)block->variables.size(); ++memberNdx) 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (&block->variables[memberNdx] == path[1].getDeclaration()) 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block->variables[memberNdx].layout.location != -1) 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentLocation = block->variables[memberNdx].layout.location; 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentLocation += getVariableLocationLength(block->variables[memberNdx].varType); 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find subtype location in the complex type 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getIOSubVariableLocation(path, 2, currentLocation); 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getExplicitLocationFromPath (const std::vector<VariablePathComponent>& path) 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VariableDeclaration* varDecl = (path[0].isInterfaceBlock()) ? (path[1].getDeclaration()) : (path[0].getDeclaration()); 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM) 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // inside uniform block 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path.front().isInterfaceBlock() && (path.front().getInterfaceBlock()->storage == glu::STORAGE_IN || path.front().getInterfaceBlock()->storage == glu::STORAGE_OUT)) 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // inside ioblock 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getIOBlockVariableLocation(path); 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varDecl->storage == glu::STORAGE_UNIFORM) 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // default block uniform 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return varDecl->layout.location; 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (varDecl->storage == glu::STORAGE_IN || varDecl->storage == glu::STORAGE_OUT) 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // default block input/output 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getIOSubVariableLocation(path, 1, varDecl->layout.location); 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid LocationValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isAtomicCounterUniform = glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType()); 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isUniformBlockVariable = path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_UNIFORM; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isVertexShader = m_filter.getShaderTypeFilter() == glu::SHADERTYPE_VERTEX; 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isFragmentShader = m_filter.getShaderTypeFilter() == glu::SHADERTYPE_FRAGMENT; 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isInputVariable = (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage == glu::STORAGE_IN) : (path.front().getDeclaration()->storage == glu::STORAGE_IN); 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isOutputVariable = (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage == glu::STORAGE_OUT) : (path.front().getDeclaration()->storage == glu::STORAGE_OUT); 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int explicitLayoutLocation = getExplicitLocationFromPath(path); 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool expectLocation; 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string reasonStr; 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isAtomicCounterUniform) 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectLocation = false; 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reasonStr = "Atomic counter uniforms have effective location of -1"; 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (isUniformBlockVariable) 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectLocation = false; 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reasonStr = "Uniform block variables have effective location of -1"; 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (isInputVariable && !isVertexShader && explicitLayoutLocation == -1) 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectLocation = false; 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reasonStr = "Inputs (except for vertex shader inputs) not declared with a location layout qualifier have effective location of -1"; 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (isOutputVariable && !isFragmentShader && explicitLayoutLocation == -1) 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectLocation = false; 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reasonStr = "Outputs (except for fragment shader outputs) not declared with a location layout qualifier have effective location of -1"; 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expectLocation = true; 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!expectLocation) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform location, expecting -1. (" << reasonStr << ")" << tcu::TestLog::EndMessage; 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != -1) 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource location invalid"); 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool locationOk; 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (explicitLayoutLocation == -1) 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting a valid location" << tcu::TestLog::EndMessage; 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry locationOk = (propValue != -1); 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting " << explicitLayoutLocation << tcu::TestLog::EndMessage; 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry locationOk = (propValue == explicitLayoutLocation); 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!locationOk) 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource location invalid"); 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent nullComponent; 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariablePathComponent& enclosingcomponent = (path.size() > 1) ? (path[path.size()-2]) : (nullComponent); 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isArray = enclosingcomponent.isVariableType() && enclosingcomponent.getVariableType()->isArrayType(); 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderContext.getFunctions(); 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (path.front().isInterfaceBlock()) ? (path.front().getInterfaceBlock()->storage) : (path.front().getDeclaration()->storage); 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLenum interface = getProgramDefaultBlockInterfaceFromStorage(storage); 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Comparing location to the values returned by GetProgramResourceLocation" << tcu::TestLog::EndMessage; 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Test all bottom-level array elements 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isArray) 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string arrayResourceName = (resource.size() > 3) ? (resource.substr(0, resource.size() - 3)) : (""); // chop "[0]" 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int arrayElementNdx = 0; arrayElementNdx < enclosingcomponent.getVariableType()->getArraySize(); ++arrayElementNdx) 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string elementResourceName = arrayResourceName + "[" + de::toString(arrayElementNdx) + "]"; 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLint location = gl.getProgramResourceLocation(m_programID, interface, elementResourceName.c_str()); 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (location != propValue+arrayElementNdx) 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tError, getProgramResourceLocation (resource=\"" << elementResourceName << "\") returned location " << location 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", expected " << (propValue+arrayElementNdx) 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource location invalid"); 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tLocation of \"" << elementResourceName << "\":\t" << location << tcu::TestLog::EndMessage; 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLint location = gl.getProgramResourceLocation(m_programID, interface, resource.c_str()); 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (location != propValue) 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, getProgramResourceLocation returned location " << location << ", expected " << propValue << tcu::TestLog::EndMessage; 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource location invalid"); 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid LocationValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 9578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{ 9588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry DE_UNREF(resource); 9598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 9608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // built-ins have no location 9618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 9628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying location, expecting -1" << tcu::TestLog::EndMessage; 9638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 9648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry if (propValue != -1) 9658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry { 9668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 9678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry setError("resource location invalid"); 9688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry } 9698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} 9708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VariableNameLengthValidator : public SingleVariableValidator 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableNameLengthValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateNameLength (const std::string& resource, glw::GLint propValue) const; 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableNameLengthValidator::VariableNameLengthValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter) 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableNameLengthValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(path); 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validateNameLength(resource, propValue); 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableNameLengthValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validateNameLength(resource, propValue); 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableNameLengthValidator::validateNameLength (const std::string& resource, glw::GLint propValue) const 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int expected = (int)resource.length() + 1; // includes null byte 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)resource.length() << " for \"" << resource << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage; 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != expected) 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage; 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("name length invalid"); 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OffsetValidator : public SingleVariableValidator 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OffsetValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOffsetValidator::OffsetValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_OFFSET, programID, filter) 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid OffsetValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isAtomicCounterUniform = glu::isDataTypeAtomicCounter(path.back().getVariableType()->getBasicType()); 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isBufferBackedBlockStorage = path.front().isInterfaceBlock() && isBufferBackedInterfaceBlockStorage(path.front().getInterfaceBlock()->storage); 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isAtomicCounterUniform && !isBufferBackedBlockStorage) 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Not buffer backed 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting -1" << tcu::TestLog::EndMessage; 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != -1) 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue << tcu::TestLog::EndMessage; 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("offset invalid"); 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Expect a valid offset 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying offset, expecting a valid offset" << tcu::TestLog::EndMessage; 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue < 0) 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid offset, got " << propValue << tcu::TestLog::EndMessage; 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("offset invalid"); 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VariableReferencedByShaderValidator : public PropValidator 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VariableReferencedByShaderValidator (Context& context, const VariableSearchFilter& searchFilter); 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getHumanReadablePropertyString (glw::GLint propVal) const; 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const; 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter m_filter; 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVariableReferencedByShaderValidator::VariableReferencedByShaderValidator (Context& context, const VariableSearchFilter& searchFilter) 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PropValidator (context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER) 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_filter (searchFilter) 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string VariableReferencedByShaderValidator::getHumanReadablePropertyString (glw::GLint propVal) const 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toString(glu::getBooleanStr(propVal)); 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VariableReferencedByShaderValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VariablePathComponent> dummyPath; 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool referencedByShader = findProgramVariablePathByPathName(dummyPath, program, resource, m_filter); 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Verifying referenced by " << glu::getShaderTypeName(m_filter.getShaderTypeFilter()) << " shader, expecting " 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE")) 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != ((referencedByShader) ? (1) : (0))) 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_" << glu::getShaderTypeName(m_filter.getShaderTypeFilter()) << ", got " << propValue << tcu::TestLog::EndMessage; 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("referenced_by_" + std::string(glu::getShaderTypeName(m_filter.getShaderTypeFilter())) + " invalid"); 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BlockNameLengthValidator : public SingleBlockValidator 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockNameLengthValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter); 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue) const; 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockNameLengthValidator::BlockNameLengthValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter) 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleBlockValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH, programID, filter) 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockNameLengthValidator::validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue) const 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(instanceIndex); 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(block); 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int expected = (int)resource.length() + 1; // includes null byte 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)resource.length() << " for \"" << resource << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage; 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != expected) 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage; 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("name length invalid"); 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BufferBindingValidator : public SingleBlockValidator 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BufferBindingValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter); 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue) const; 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBufferBindingValidator::BufferBindingValidator (Context& context, const glw::GLuint programID, const VariableSearchFilter& filter) 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleBlockValidator(context, PROGRAMRESOURCEPROP_BUFFER_BINDING, programID, filter) 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BufferBindingValidator::validateSingleBlock (const glu::InterfaceBlock& block, const std::vector<int>& instanceIndex, const std::string& resource, glw::GLint propValue) const 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (block.layout.binding != -1) 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int flatIndex = 0; 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int dimensionSize = 1; 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dimensionNdx = (int)(block.dimensions.size()) - 1; dimensionNdx >= 0; --dimensionNdx) 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry flatIndex += dimensionSize * instanceIndex[dimensionNdx]; 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dimensionSize *= block.dimensions[dimensionNdx]; 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int expected = (block.dimensions.empty()) ? (block.layout.binding) : (block.layout.binding + flatIndex); 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying block binding, expecting " << expected << tcu::TestLog::EndMessage; 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != expected) 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue << tcu::TestLog::EndMessage; 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("buffer binding invalid"); 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying buffer binding, expecting a valid binding" << tcu::TestLog::EndMessage; 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue < 0) 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid buffer binding, got " << propValue << tcu::TestLog::EndMessage; 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("buffer binding invalid"); 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BlockReferencedByShaderValidator : public PropValidator 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BlockReferencedByShaderValidator (Context& context, const VariableSearchFilter& searchFilter); 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getHumanReadablePropertyString (glw::GLint propVal) const; 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const; 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter m_filter; 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11793c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBlockReferencedByShaderValidator::BlockReferencedByShaderValidator (Context& context, const VariableSearchFilter& searchFilter) 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PropValidator (context, PROGRAMRESOURCEPROP_REFERENCED_BY_SHADER) 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_filter (searchFilter) 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string BlockReferencedByShaderValidator::getHumanReadablePropertyString (glw::GLint propVal) const 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return de::toString(glu::getBooleanStr(propVal)); 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BlockReferencedByShaderValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string blockName = glu::parseVariableName(resource.c_str()); 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool referencedByShader = false; 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Shader* const shader = program->getShaders()[shaderNdx]; 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_filter.matchesFilter(shader)) 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int blockNdx = 0; blockNdx < (int)shader->getDefaultBlock().interfaceBlocks.size(); ++blockNdx) 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::InterfaceBlock& block = shader->getDefaultBlock().interfaceBlocks[blockNdx]; 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_filter.matchesFilter(block) && block.interfaceName == blockName) 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry referencedByShader = true; 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Verifying referenced by " << glu::getShaderTypeName(m_filter.getShaderTypeFilter()) << " shader, expecting " 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((referencedByShader) ? ("GL_TRUE") : ("GL_FALSE")) 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != ((referencedByShader) ? (1) : (0))) 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid referenced_by_" << glu::getShaderTypeName(m_filter.getShaderTypeFilter()) << ", got " << propValue << tcu::TestLog::EndMessage; 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("referenced_by_" + std::string(glu::getShaderTypeName(m_filter.getShaderTypeFilter())) + " invalid"); 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TopLevelArraySizeValidator : public SingleVariableValidator 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TopLevelArraySizeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTopLevelArraySizeValidator::TopLevelArraySizeValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_SIZE, programID, filter) 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TopLevelArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int expected; 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string reason; 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER); 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!path[1].getDeclaration()->varType.isArrayType()) 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expected = 1; 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reason = "Top-level block member is not an array"; 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[1].getDeclaration()->varType.getElementType().isBasicType()) 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expected = 1; 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reason = "Top-level block member is not an array of an aggregate type"; 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[1].getDeclaration()->varType.getArraySize() == glu::VarType::UNSIZED_ARRAY) 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expected = 0; 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reason = "Top-level block member is an unsized top-level array"; 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry expected = path[1].getDeclaration()->varType.getArraySize(); 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry reason = "Top-level block member is a sized top-level array"; 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array size, expecting " << expected << ". (" << reason << ")." << tcu::TestLog::EndMessage; 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != expected) 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array size, got " << propValue << tcu::TestLog::EndMessage; 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("top level array size invalid"); 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TopLevelArrayStrideValidator : public SingleVariableValidator 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TopLevelArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter); 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTopLevelArrayStrideValidator::TopLevelArrayStrideValidator (Context& context, glw::GLuint programID, const VariableSearchFilter& filter) 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : SingleVariableValidator(context, PROGRAMRESOURCEPROP_TOP_LEVEL_ARRAY_STRIDE, programID, filter) 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TopLevelArrayStrideValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(path.front().isInterfaceBlock() && path.front().getInterfaceBlock()->storage == glu::STORAGE_BUFFER); 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(resource); 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!path[1].getDeclaration()->varType.isArrayType()) 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting 0. (Top-level block member is not an array)." << tcu::TestLog::EndMessage; 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != 0) 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue << tcu::TestLog::EndMessage; 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("top level array stride invalid"); 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (path[1].getDeclaration()->varType.getElementType().isBasicType()) 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting 0. (Top-level block member is not an array of an aggregate type)." << tcu::TestLog::EndMessage; 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue != 0) 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, top level array stride, got " << propValue << tcu::TestLog::EndMessage; 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("top level array stride invalid"); 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int minimumStride = getVarTypeSize(path[1].getDeclaration()->varType.getElementType()); 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying top level array stride, expecting greater or equal to " << minimumStride << "." << tcu::TestLog::EndMessage; 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValue < minimumStride) 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid top level array stride, got " << propValue << tcu::TestLog::EndMessage; 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("top level array stride invalid"); 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 132679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryclass TransformFeedbackResourceValidator : public PropValidator 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 132979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry TransformFeedbackResourceValidator (Context& context, ProgramResourcePropFlags validationProp); 133079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const; 133179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 133279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryprivate: 133379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry virtual void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const = 0; 133479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry virtual void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const = 0; 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 133779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 133879ec52223daa917719d5d0555e7d8020d6514951Jarkko PöyryTransformFeedbackResourceValidator::TransformFeedbackResourceValidator (Context& context, ProgramResourcePropFlags validationProp) 133979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry : PropValidator(context, validationProp) 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 134379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackResourceValidator::validate (const ProgramInterfaceDefinition::Program* program, const std::string& resource, glw::GLint propValue) const 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (deStringBeginsWith(resource.c_str(), "gl_")) 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 134779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry validateBuiltinVariable(resource, propValue); 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 135179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Check resource name is a xfb output. (sanity check) 135279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry#if defined(DE_DEBUG) 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool generatorFound = false; 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 135579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Check the resource name is a valid transform feedback resource and find the name generating resource 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int varyingNdx = 0; varyingNdx < (int)program->getTransformFeedbackVaryings().size(); ++varyingNdx) 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 135879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const std::string varyingName = program->getTransformFeedbackVaryings()[varyingNdx]; 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<VariablePathComponent> path; 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::string> resources; 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!findProgramVariablePathByPathName(path, program, varyingName, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_OUT))) 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program does not contain feedback varying, not valid program 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 136979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry generateVariableTypeResourceNames(resources, varyingName, *path.back().getVariableType(), RESOURCE_NAME_GENERATION_FLAG_TRANSFORM_FEEDBACK_VARIABLE); 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::contains(resources.begin(), resources.end(), resource)) 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry generatorFound = true; 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 137879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // resource name was not found, should never happen 137979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(generatorFound); 138079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_UNREF(generatorFound); 138179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry#endif 138279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 138379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // verify resource 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 138579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry std::vector<VariablePathComponent> path; 138679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 138779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (!findProgramVariablePathByPathName(path, program, resource, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_OUT))) 138879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(false); 138979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 139079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry validateSingleVariable(path, resource, propValue); 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 139379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 139479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 139579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryclass TransformFeedbackArraySizeValidator : public TransformFeedbackResourceValidator 139679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 139779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyrypublic: 139879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry TransformFeedbackArraySizeValidator (Context& context); 139979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 140079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 140179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 140279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry}; 140379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 140479ec52223daa917719d5d0555e7d8020d6514951Jarkko PöyryTransformFeedbackArraySizeValidator::TransformFeedbackArraySizeValidator (Context& context) 140579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_ARRAY_SIZE) 140679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 140779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 140879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 140979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackArraySizeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 141079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 141179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry int arraySize = 0; 141279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 141379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (resource == "gl_Position") 141479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry arraySize = 1; 141579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry else 141679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(false); 141779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 141879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage; 141979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (arraySize != propValue) 142079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 142179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 142279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry setError("resource array size invalid"); 142379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 142479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 142579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 142679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackArraySizeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 142779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 142879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_UNREF(resource); 142979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 143079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const int arraySize = (path.back().getVariableType()->isArrayType()) ? (path.back().getVariableType()->getArraySize()) : (1); 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying array size, expecting " << arraySize << tcu::TestLog::EndMessage; 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (arraySize != propValue) 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << propValue << tcu::TestLog::EndMessage; 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setError("resource array size invalid"); 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 144079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryclass TransformFeedbackNameLengthValidator : public TransformFeedbackResourceValidator 144179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 144279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyrypublic: 144379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry TransformFeedbackNameLengthValidator (Context& context); 144479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 144579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryprivate: 144679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 144779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 144879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateVariable (const std::string& resource, glw::GLint propValue) const; 144979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry}; 145079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 145179ec52223daa917719d5d0555e7d8020d6514951Jarkko PöyryTransformFeedbackNameLengthValidator::TransformFeedbackNameLengthValidator (Context& context) 145279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_NAME_LENGTH) 145379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 145479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 145579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 145679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackNameLengthValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 145779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 145879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry validateVariable(resource, propValue); 145979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 146079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 146179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackNameLengthValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 146279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 146379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_UNREF(path); 146479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry validateVariable(resource, propValue); 146579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 146679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 146779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackNameLengthValidator::validateVariable (const std::string& resource, glw::GLint propValue) const 146879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 146979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const int expected = (int)resource.length() + 1; // includes null byte 147079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying name length, expecting " << expected << " (" << (int)resource.length() << " for \"" << resource << "\" + 1 byte for terminating null character)" << tcu::TestLog::EndMessage; 147179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 147279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (propValue != expected) 147379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 147479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, invalid name length, got " << propValue << tcu::TestLog::EndMessage; 147579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry setError("name length invalid"); 147679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 147779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 147879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 147979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryclass TransformFeedbackTypeValidator : public TransformFeedbackResourceValidator 148079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 148179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyrypublic: 148279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry TransformFeedbackTypeValidator (Context& context); 148379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 148479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const; 148579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry void validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const; 148679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry}; 148779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 148879ec52223daa917719d5d0555e7d8020d6514951Jarkko PöyryTransformFeedbackTypeValidator::TransformFeedbackTypeValidator (Context& context) 148979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry : TransformFeedbackResourceValidator(context, PROGRAMRESOURCEPROP_TYPE) 149079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 149179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 149279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 149379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackTypeValidator::validateBuiltinVariable (const std::string& resource, glw::GLint propValue) const 149479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 149579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry glu::DataType varType = glu::TYPE_INVALID; 149679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 149779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (resource == "gl_Position") 149879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry varType = glu::TYPE_FLOAT_VEC4; 149979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry else 150079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(false); 150179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 150279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(varType) << tcu::TestLog::EndMessage; 150379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (glu::getDataTypeFromGLType(propValue) != varType) 150479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 150579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage; 150679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry setError("resource type invalid"); 150779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 150879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry return; 150979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 151079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 151179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyryvoid TransformFeedbackTypeValidator::validateSingleVariable (const std::vector<VariablePathComponent>& path, const std::string& resource, glw::GLint propValue) const 151279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry{ 151379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_UNREF(resource); 151479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 151579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Unlike other interfaces, xfb program interface uses just variable name to refer to arrays of basic types. (Others use "variable[0]") 151679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry // Thus we might end up querying a type for an array. In this case, return the type of an array element. 151779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const glu::VarType& variable = *path.back().getVariableType(); 151879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const glu::VarType& elementType = (variable.isArrayType()) ? (variable.getElementType()) : (variable); 151979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 152079ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry DE_ASSERT(elementType.isBasicType()); 152179ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 152279ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying type, expecting " << glu::getDataTypeName(elementType.getBasicType()) << tcu::TestLog::EndMessage; 152379ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry if (elementType.getBasicType() != glu::getDataTypeFromGLType(propValue)) 152479ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry { 152579ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "\tError, got " << glu::getDataTypeName(glu::getDataTypeFromGLType(propValue)) << tcu::TestLog::EndMessage; 152679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry setError("resource type invalid"); 152779ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry } 152879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry} 152979ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramResourceQueryTestTarget::ProgramResourceQueryTestTarget (ProgramInterface interface_, deUint32 propFlags_) 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : interface(interface_) 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , propFlags(propFlags_) 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (interface) 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_INTERFACE_MASK) == propFlags); break; 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM_BLOCK: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_UNIFORM_BLOCK_INTERFACE_MASK) == propFlags); break; 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_SHADER_STORAGE_BLOCK_MASK) == propFlags); break; 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_INPUT: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_INPUT_MASK) == propFlags); break; 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_OUTPUT: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_PROGRAM_OUTPUT_MASK) == propFlags); break; 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_BUFFER_VARIABLE: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_BUFFER_VARIABLE_MASK) == propFlags); break; 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING: DE_ASSERT((propFlags & PROGRAMRESOURCEPROP_TRANSFORM_FEEDBACK_VARYING_MASK) == propFlags); break; 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterfaceQueryTestCase::ProgramInterfaceQueryTestCase (Context& context, const char* name, const char* description, ProgramResourceQueryTestTarget queryTarget) 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_queryTarget (queryTarget) 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterfaceQueryTestCase::~ProgramInterfaceQueryTestCase (void) 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterface ProgramInterfaceQueryTestCase::getTargetInterface (void) const 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_queryTarget.interface; 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glw::GLenum getGLInterfaceEnumValue (ProgramInterface interface) 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (interface) 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM: return GL_UNIFORM; 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM_BLOCK: return GL_UNIFORM_BLOCK; 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_ATOMIC_COUNTER_BUFFER: return GL_ATOMIC_COUNTER_BUFFER; 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_INPUT: return GL_PROGRAM_INPUT; 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_OUTPUT: return GL_PROGRAM_OUTPUT; 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING: return GL_TRANSFORM_FEEDBACK_VARYING; 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_BUFFER_VARIABLE: return GL_BUFFER_VARIABLE; 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK: return GL_SHADER_STORAGE_BLOCK; 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void queryAndValidateProps (tcu::TestContext& testCtx, const glw::Functions& gl, glw::GLuint programID, ProgramInterface interface, const char* targetResourceName, const ProgramInterfaceDefinition::Program* programDefinition, const std::vector<glw::GLenum>& props, const std::vector<const PropValidator*>& validators) 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLenum glInterface = getGLInterfaceEnumValue(interface); 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint resourceNdx; 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLint written = -1; 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLint> propValues (props.size() + 1, -2); // prefill result buffer with an invalid value. -1 might be valid sometimes, avoid it. Make buffer one larger to allow detection of too many return values 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(props.size() == validators.size()); 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // query 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resourceNdx = gl.getProgramResourceIndex(programID, glInterface, targetResourceName); 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index"); 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resourceNdx == GL_INVALID_INDEX) 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceIndex returned GL_INVALID_INDEX for \"" << targetResourceName << "\"" << tcu::TestLog::EndMessage; 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.setTestResult(QP_TEST_RESULT_FAIL, "could not find target resource"); 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // try to recover but keep the test result as failure 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string resourceName = std::string(targetResourceName); 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string simplifiedResourceName; 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (stringEndsWith(resourceName, "[0]")) 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry simplifiedResourceName = resourceName.substr(0, resourceName.length() - 3); 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const size_t lastMember = resourceName.find_last_of('.'); 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (lastMember != std::string::npos) 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry simplifiedResourceName = resourceName.substr(0, lastMember); 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (simplifiedResourceName.empty()) 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resourceNdx = gl.getProgramResourceIndex(programID, glInterface, simplifiedResourceName.c_str()); 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "get resource index"); 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (resourceNdx == GL_INVALID_INDEX) 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.getLog() << tcu::TestLog::Message << "\tResource not found, continuing anyway using index obtained for resource \"" << simplifiedResourceName << "\"" << tcu::TestLog::EndMessage; 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getProgramResourceiv(programID, glInterface, resourceNdx, (int)props.size(), &props[0], (int)propValues.size(), &written, &propValues[0]); 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "get props"); 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (written != (int)props.size()) 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceiv returned unexpected number of values, expected " << (int)props.size() << ", got " << written << tcu::TestLog::EndMessage; 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values"); 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (propValues.back() != -2) 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.getLog() << tcu::TestLog::Message << "getProgramResourceiv post write buffer guard value was modified, too many return values" << tcu::TestLog::EndMessage; 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry testCtx.setTestResult(QP_TEST_RESULT_FAIL, "getProgramResourceiv returned unexpected number of values"); 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return; 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry propValues.pop_back(); 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(validators.size() == propValues.size()); 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // log 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MessageBuilder message(&testCtx.getLog()); 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry message << "For resource index " << resourceNdx << " (\"" << targetResourceName << "\") got following properties:\n"; 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx) 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry message << "\t" << glu::getProgramResourcePropertyName(props[propNdx]) << ":\t" << validators[propNdx]->getHumanReadablePropertyString(propValues[propNdx]) << "\n"; 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry message << tcu::TestLog::EndMessage; 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // validate 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < (int)propValues.size(); ++propNdx) 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators[propNdx]->validate(programDefinition, targetResourceName, propValues[propNdx]); 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryProgramInterfaceQueryTestCase::IterateResult ProgramInterfaceQueryTestCase::iterate (void) 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct TestProperty 16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum prop; 16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const PropValidator* validator; 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::Program* programDefinition = getProgramDefinition(); 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<std::string> targetResources = getQueryTargetResources(); 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram program (m_context.getRenderContext(), generateProgramInterfaceProgramSources(programDefinition)); 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(programDefinition->isValid()); 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log program 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program", "Program"); 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Feedback varyings 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!programDefinition->getTransformFeedbackVaryings().empty()) 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MessageBuilder builder(&m_testCtx.getLog()); 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "Transform feedback varyings: {"; 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)programDefinition->getTransformFeedbackVaryings().size(); ++ndx) 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ndx) 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << ", "; 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "\"" << programDefinition->getTransformFeedbackVaryings()[ndx] << "\""; 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry builder << "}" << tcu::TestLog::EndMessage; 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << program; 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program.isOk()) 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Program build failed, checking if program exceeded implementation limits" << tcu::TestLog::EndMessage; 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkProgramResourceUsage(programDefinition, m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // within limits 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check interface props 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_queryTarget.interface) 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM: 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter uniformFilter (glu::SHADERTYPE_LAST, glu::STORAGE_UNIFORM); 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TypeValidator typeValidator (m_context, program.getProgram(), uniformFilter); 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArraySizeValidator arraySizeValidator (m_context, program.getProgram(), uniformFilter); 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArrayStrideValidator arrayStrideValidator (m_context, program.getProgram(), uniformFilter); 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockIndexValidator blockIndexValidator (m_context, program.getProgram(), uniformFilter); 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IsRowMajorValidator isRowMajorValidator (m_context, program.getProgram(), uniformFilter); 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const MatrixStrideValidator matrixStrideValidator (m_context, program.getProgram(), uniformFilter); 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const AtomicCounterBufferIndexVerifier atomicCounterBufferIndexVerifier (m_context, program.getProgram(), uniformFilter); 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LocationValidator locationValidator (m_context, program.getProgram(), uniformFilter); 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableNameLengthValidator nameLengthValidator (m_context, program.getProgram(), uniformFilter); 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const OffsetValidator offsetVerifier (m_context, program.getProgram(), uniformFilter); 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByVertexVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_UNIFORM)); 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByFragmentVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_FRAGMENT, glu::STORAGE_UNIFORM)); 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByComputeVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_COMPUTE, glu::STORAGE_UNIFORM)); 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestProperty allProperties[] = 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_SIZE, &arraySizeValidator }, 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_STRIDE, &arrayStrideValidator }, 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ATOMIC_COUNTER_BUFFER_INDEX, &atomicCounterBufferIndexVerifier }, 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_BLOCK_INDEX, &blockIndexValidator }, 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_IS_ROW_MAJOR, &isRowMajorValidator }, 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_LOCATION, &locationValidator }, 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MATRIX_STRIDE, &matrixStrideValidator }, 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_NAME_LENGTH, &nameLengthValidator }, 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_OFFSET, &offsetVerifier }, 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier }, 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier }, 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier }, 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TYPE, &typeValidator }, 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx) 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "UniformResource", "Uniform resource \"" + targetResources[targetResourceNdx] + "\""); 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLenum> props; 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const PropValidator*> validators; 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx) 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) && 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allProperties[propNdx].validator->isSupported()) 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry props.push_back(allProperties[propNdx].prop); 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators.push_back(allProperties[propNdx].validator); 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!props.empty()); 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators); 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_UNIFORM_BLOCK: 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_SHADER_STORAGE_BLOCK: 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (m_queryTarget.interface == PROGRAMINTERFACE_UNIFORM_BLOCK) ? (glu::STORAGE_UNIFORM) : (glu::STORAGE_BUFFER); 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter blockFilter (glu::SHADERTYPE_LAST, storage); 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockNameLengthValidator nameLengthValidator (m_context, program.getProgram(), blockFilter); 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockReferencedByShaderValidator referencedByVertexVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_VERTEX, storage)); 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockReferencedByShaderValidator referencedByFragmentVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_FRAGMENT, storage)); 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockReferencedByShaderValidator referencedByComputeVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_COMPUTE, storage)); 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BufferBindingValidator bufferBindingValidator (m_context, program.getProgram(), blockFilter); 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestProperty allProperties[] = 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_NAME_LENGTH, &nameLengthValidator }, 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier }, 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier }, 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier }, 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_BUFFER_BINDING, &bufferBindingValidator }, 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx) 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "BlockResource", "Interface block \"" + targetResources[targetResourceNdx] + "\""); 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLenum> props; 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const PropValidator*> validators; 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx) 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) && 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allProperties[propNdx].validator->isSupported()) 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry props.push_back(allProperties[propNdx].prop); 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators.push_back(allProperties[propNdx].validator); 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!props.empty()); 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators); 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_INPUT: 18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_PROGRAM_OUTPUT: 18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Storage storage = (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (glu::STORAGE_IN) : (glu::STORAGE_OUT); 18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ShaderType shaderType = (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? (programDefinition->getFirstStage()) : (programDefinition->getLastStage()); 18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter variableFilter (shaderType, storage); 18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TypeValidator typeValidator (m_context, program.getProgram(), variableFilter); 18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArraySizeValidator arraySizeValidator (m_context, program.getProgram(), variableFilter); 18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LocationValidator locationValidator (m_context, program.getProgram(), variableFilter); 18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableNameLengthValidator nameLengthValidator (m_context, program.getProgram(), variableFilter); 18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByVertexVerifier (m_context, VariableSearchFilter::intersection(VariableSearchFilter(glu::SHADERTYPE_VERTEX, storage), variableFilter)); 18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByFragmentVerifier (m_context, VariableSearchFilter::intersection(VariableSearchFilter(glu::SHADERTYPE_FRAGMENT, storage), variableFilter)); 18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByComputeVerifier (m_context, VariableSearchFilter::intersection(VariableSearchFilter(glu::SHADERTYPE_COMPUTE, storage), variableFilter)); 18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestProperty allProperties[] = 18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_SIZE, &arraySizeValidator }, 18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_LOCATION, &locationValidator }, 18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_NAME_LENGTH, &nameLengthValidator }, 18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier }, 18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier }, 18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier }, 18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TYPE, &typeValidator }, 18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx) 18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string resourceInterfaceName = (m_queryTarget.interface == PROGRAMINTERFACE_PROGRAM_INPUT) ? ("Input") : ("Output"); 18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "BlockResource", resourceInterfaceName + " resource \"" + targetResources[targetResourceNdx] + "\""); 18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLenum> props; 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const PropValidator*> validators; 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx) 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) && 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allProperties[propNdx].validator->isSupported()) 18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry props.push_back(allProperties[propNdx].prop); 18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators.push_back(allProperties[propNdx].validator); 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!props.empty()); 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators); 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_BUFFER_VARIABLE: 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableSearchFilter variableFilter (glu::SHADERTYPE_LAST, glu::STORAGE_BUFFER); 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TypeValidator typeValidator (m_context, program.getProgram(), variableFilter); 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArraySizeValidator arraySizeValidator (m_context, program.getProgram(), variableFilter); 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ArrayStrideValidator arrayStrideValidator (m_context, program.getProgram(), variableFilter); 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const BlockIndexValidator blockIndexValidator (m_context, program.getProgram(), variableFilter); 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IsRowMajorValidator isRowMajorValidator (m_context, program.getProgram(), variableFilter); 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const MatrixStrideValidator matrixStrideValidator (m_context, program.getProgram(), variableFilter); 18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const OffsetValidator offsetValidator (m_context, program.getProgram(), variableFilter); 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableNameLengthValidator nameLengthValidator (m_context, program.getProgram(), variableFilter); 18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByVertexVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_VERTEX, glu::STORAGE_BUFFER)); 18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByFragmentVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_FRAGMENT, glu::STORAGE_BUFFER)); 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VariableReferencedByShaderValidator referencedByComputeVerifier (m_context, VariableSearchFilter(glu::SHADERTYPE_COMPUTE, glu::STORAGE_BUFFER)); 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TopLevelArraySizeValidator topLevelArraySizeValidator (m_context, program.getProgram(), variableFilter); 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TopLevelArrayStrideValidator topLevelArrayStrideValidator (m_context, program.getProgram(), variableFilter); 18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestProperty allProperties[] = 18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_SIZE, &arraySizeValidator }, 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_STRIDE, &arrayStrideValidator }, 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_BLOCK_INDEX, &blockIndexValidator }, 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_IS_ROW_MAJOR, &isRowMajorValidator }, 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MATRIX_STRIDE, &matrixStrideValidator }, 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_NAME_LENGTH, &nameLengthValidator }, 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_OFFSET, &offsetValidator }, 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_VERTEX_SHADER, &referencedByVertexVerifier }, 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_FRAGMENT_SHADER, &referencedByFragmentVerifier }, 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_REFERENCED_BY_COMPUTE_SHADER, &referencedByComputeVerifier }, 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TOP_LEVEL_ARRAY_SIZE, &topLevelArraySizeValidator }, 19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TOP_LEVEL_ARRAY_STRIDE, &topLevelArrayStrideValidator }, 19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TYPE, &typeValidator }, 19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx) 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "BufferVariableResource", "Buffer variable \"" + targetResources[targetResourceNdx] + "\""); 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLenum> props; 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const PropValidator*> validators; 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx) 19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) && 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allProperties[propNdx].validator->isSupported()) 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry props.push_back(allProperties[propNdx].prop); 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators.push_back(allProperties[propNdx].validator); 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!props.empty()); 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators); 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case PROGRAMINTERFACE_TRANSFORM_FEEDBACK_VARYING: 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 193679ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const TransformFeedbackTypeValidator typeValidator (m_context); 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TransformFeedbackArraySizeValidator arraySizeValidator (m_context); 193879ec52223daa917719d5d0555e7d8020d6514951Jarkko Pöyry const TransformFeedbackNameLengthValidator nameLengthValidator (m_context); 19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TestProperty allProperties[] = 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_ARRAY_SIZE, &arraySizeValidator }, 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_NAME_LENGTH, &nameLengthValidator }, 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_TYPE, &typeValidator }, 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int targetResourceNdx = 0; targetResourceNdx < (int)targetResources.size(); ++targetResourceNdx) 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "XFBVariableResource", "Transform feedback varying \"" + targetResources[targetResourceNdx] + "\""); 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<glw::GLenum> props; 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<const PropValidator*> validators; 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int propNdx = 0; propNdx < DE_LENGTH_OF_ARRAY(allProperties); ++propNdx) 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allProperties[propNdx].validator->isSelected(m_queryTarget.propFlags) && 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allProperties[propNdx].validator->isSupported()) 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry props.push_back(allProperties[propNdx].prop); 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry validators.push_back(allProperties[propNdx].validator); 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!props.empty()); 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry queryAndValidateProps(m_testCtx, gl, program.getProgram(), m_queryTarget.interface, targetResources[targetResourceNdx].c_str(), programDefinition, props, validators); 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool checkLimit (glw::GLenum pname, int usage, const glw::Functions& gl, tcu::TestLog& log) 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (usage > 0) 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLint limit = 0; 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(pname, &limit); 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query limits"); 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "\t" << glu::getGettableStateStr(pname) << " = " << limit << ", test requires " << usage << tcu::TestLog::EndMessage; 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (limit < usage) 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "\t\tLimit exceeded" << tcu::TestLog::EndMessage; 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool checkShaderResourceUsage (const ProgramInterfaceDefinition::Shader* shader, const glw::Functions& gl, tcu::TestLog& log) 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::ShaderResourceUsage usage = getShaderResourceUsage(shader); 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (shader->getType()) 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_VERTEX: 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum pname; 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int usage; 20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } restrictions[] = 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_ATTRIBS, usage.numInputVectors }, 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents }, 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_UNIFORM_VECTORS, usage.numUniformVectors }, 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_UNIFORM_BLOCKS, usage.numUniformBlocks }, 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_OUTPUT_COMPONENTS, usage.numOutputComponents }, 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, usage.numSamplers }, 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers }, 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_ATOMIC_COUNTERS, usage.numAtomicCounters }, 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_IMAGE_UNIFORMS, usage.numImages }, 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents }, 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks }, 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "Vertex shader:" << tcu::TestLog::EndMessage; 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx) 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log); 20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_FRAGMENT: 20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum pname; 20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int usage; 20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } restrictions[] = 20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents }, 20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_UNIFORM_VECTORS, usage.numUniformVectors }, 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_UNIFORM_BLOCKS, usage.numUniformBlocks }, 20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_INPUT_COMPONENTS, usage.numInputComponents }, 20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_TEXTURE_IMAGE_UNITS, usage.numSamplers }, 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers }, 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_ATOMIC_COUNTERS, usage.numAtomicCounters }, 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_IMAGE_UNIFORMS, usage.numImages }, 20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents }, 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks }, 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "Fragment shader:" << tcu::TestLog::EndMessage; 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx) 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log); 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case glu::SHADERTYPE_COMPUTE: 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum pname; 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int usage; 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } restrictions[] = 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_UNIFORM_BLOCKS, usage.numUniformBlocks }, 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, usage.numSamplers }, 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_UNIFORM_COMPONENTS, usage.numDefaultBlockUniformComponents }, 20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers }, 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_ATOMIC_COUNTERS, usage.numAtomicCounters }, 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_IMAGE_UNIFORMS, usage.numImages }, 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS, usage.numCombinedUniformComponents }, 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks }, 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "Compute shader:" << tcu::TestLog::EndMessage; 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx) 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log); 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool checkProgramCombinedResourceUsage (const ProgramInterfaceDefinition::Program* program, const glw::Functions& gl, tcu::TestLog& log) 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const ProgramInterfaceDefinition::ProgramResourceUsage usage = getCombinedProgramResourceUsage(program); 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum pname; 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int usage; 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } restrictions[] = 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_UNIFORM_BUFFER_BINDINGS, usage.uniformBufferMaxBinding+1 }, 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_UNIFORM_BLOCK_SIZE, usage.uniformBufferMaxSize }, 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_UNIFORM_BLOCKS, usage.numUniformBlocks }, 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, usage.numCombinedVertexUniformComponents }, 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, usage.numCombinedFragmentUniformComponents }, 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VARYING_COMPONENTS, usage.numVaryingComponents }, 21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_VARYING_VECTORS, usage.numVaryingVectors }, 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, usage.numCombinedSamplers }, 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES, usage.numCombinedOutputResources }, 21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, usage.atomicCounterBufferMaxBinding+1 }, 21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, usage.atomicCounterBufferMaxSize }, 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, usage.numAtomicCounterBuffers }, 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_ATOMIC_COUNTERS, usage.numAtomicCounters }, 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_IMAGE_UNITS, usage.maxImageBinding }, 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_IMAGE_UNIFORMS, usage.numCombinedImages }, 21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, usage.shaderStorageBufferMaxBinding+1 }, 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_SHADER_STORAGE_BLOCK_SIZE, usage.shaderStorageBufferMaxSize }, 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, usage.numShaderStorageBlocks }, 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, usage.numXFBInterleavedComponents }, 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, usage.numXFBSeparateAttribs }, 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, usage.numXFBSeparateComponents }, 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "Program combined:" << tcu::TestLog::EndMessage; 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(restrictions); ++ndx) 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk &= checkLimit(restrictions[ndx].pname, restrictions[ndx].usage, gl, log); 21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return allOk; 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid checkProgramResourceUsage (const ProgramInterfaceDefinition::Program* program, const glw::Functions& gl, tcu::TestLog& log) 21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool limitExceeded = false; 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int shaderNdx = 0; shaderNdx < (int)program->getShaders().size(); ++shaderNdx) 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry limitExceeded |= !checkShaderResourceUsage(program->getShaders()[shaderNdx], gl, log); 21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry limitExceeded |= !checkProgramCombinedResourceUsage(program, gl, log); 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (limitExceeded) 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << tcu::TestLog::Message << "One or more resource limits exceeded" << tcu::TestLog::EndMessage; 21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("one or more resource limits exceeded"); 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 2158