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 Tessellation Tests. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fTessellationTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp" 2618c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry#include "glsShaderLibrary.hpp" 27c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#include "glsStateQueryUtil.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarType.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluVarTypeUtil.hpp" 37c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry#include "gluCallLogWrapper.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp" 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp" 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageIO.hpp" 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuResource.hpp" 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp" 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp" 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h" 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwDefs.hpp" 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string> 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <functional> 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set> 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits> 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderProgram; 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::RenderContext; 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RenderTarget; 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3; 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4; 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::Random; 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr; 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; // For GL types. 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::RandomViewport; 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 88c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryusing namespace gls::StateQueryUtil; 89c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MINIMUM_MAX_TESS_GEN_LEVEL = 64 //!< GL-defined minimum for GL_MAX_TESS_GEN_LEVEL. 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool vec3XLessThan (const Vec3& a, const Vec3& b) { return a.x() < b.x(); } 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename IterT> 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string elemsStr (const IterT& begin, const IterT& end, int wrapLengthParam = 0, int numIndentationSpaces = 0) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string baseIndentation = string(numIndentationSpaces, ' '); 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string deepIndentation = baseIndentation + string(4, ' '); 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int wrapLength = wrapLengthParam > 0 ? wrapLengthParam : std::numeric_limits<int>::max(); 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int length = (int)std::distance(begin, end); 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (length > wrapLength) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += "(amount: " + de::toString(length) + ") "; 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += string() + "{" + (length > wrapLength ? "\n"+deepIndentation : " "); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int index = 0; 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (IterT it = begin; it != end; ++it) 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (it != begin) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += string() + ", " + (index % wrapLength == 0 ? "\n"+deepIndentation : ""); 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += de::toString(*it); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry index++; 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += length > wrapLength ? "\n"+baseIndentation : " "; 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += "}"; 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerT> 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string containerStr (const ContainerT& c, int wrapLengthParam = 0, int numIndentationSpaces = 0) 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return elemsStr(c.begin(), c.end(), wrapLengthParam, numIndentationSpaces); 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int N> 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string arrayStr (const T (&arr)[N], int wrapLengthParam = 0, int numIndentationSpaces = 0) 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return elemsStr(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr), wrapLengthParam, numIndentationSpaces); 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int N> 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic T arrayMax (const T (&arr)[N]) 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return *std::max_element(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr)); 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename MembT> 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<MembT> members (const vector<T>& objs, MembT T::* membP) 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<MembT> result(objs.size()); 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)objs.size(); i++) 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result[i] = objs[i].*membP; 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, int N> 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<T> arrayToVector (const T (&arr)[N]) 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vector<T>(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr)); 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ContainerT, typename T> 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool contains (const ContainerT& c, const T& key) 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return c.find(key) != c.end(); 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vector<bool, Size> singleTrueMask (int index) 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inBounds(index, 0, Size)); 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vector<bool, Size> result; 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result[index] = true; 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int intPow (int base, int exp) 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(exp >= 0); 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (exp == 0) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int sub = intPow(base, exp/2); 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (exp % 2 == 0) 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sub*sub; 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return sub*sub*base; 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Surface getPixels (const glu::RenderContext& rCtx, int x, int y, int width, int height) 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface result(width, height); 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(rCtx, x, y, result.getAccess()); 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Surface getPixels (const glu::RenderContext& rCtx, const RandomViewport& vp) 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getPixels(rCtx, vp.x, vp.y, vp.width, vp.height); 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void checkRenderTargetSize (const RenderTarget& renderTarget, int minSize) 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderTarget.getWidth() < minSize || renderTarget.getHeight() < minSize) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Render target width and height must be at least " + de::toString(minSize)); 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureLevel getPNG (const tcu::Archive& archive, const string& filename) 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TextureLevel result; 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::ImageIO::loadPNG(result, archive, filename.c_str()); 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int numBasicSubobjects (const glu::VarType& type) 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type.isBasicType()) 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isArrayType()) 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return type.getArraySize()*numBasicSubobjects(type.getElementType()); 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (type.isStructType()) 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::StructType& structType = *type.getStructPtr(); 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = 0; 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < structType.getNumMembers(); i++) 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += numBasicSubobjects(structType.getMember(i).getType()); 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int numVerticesPerPrimitive (deUint32 primitiveTypeGL) 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primitiveTypeGL) 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GL_POINTS: return 1; 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GL_TRIANGLES: return 3; 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GL_LINES: return 2; 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void setViewport (const glw::Functions& gl, const RandomViewport& vp) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(vp.x, vp.y, vp.width, vp.height); 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 getQueryResult (const glw::Functions& gl, deUint32 queryObject) 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 result = (deUint32)-1; 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getQueryObjectuiv(queryObject, GL_QUERY_RESULT, &result); 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(result != (deUint32)-1); 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void readDataMapped (const glw::Functions& gl, deUint32 bufferTarget, int numElems, T* dst) 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numBytes = numElems*(int)sizeof(T); 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const T* const mappedData = (const T*)gl.mapBufferRange(bufferTarget, 0, numBytes, GL_MAP_READ_BIT); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), (string() + "glMapBufferRange(" + glu::getBufferTargetName((int)bufferTarget) + ", 0, " + de::toString(numBytes) + ", GL_MAP_READ_BIT)").c_str()); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(mappedData != DE_NULL); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numElems; i++) 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst[i] = mappedData[i]; 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.unmapBuffer(bufferTarget); 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<T> readDataMapped (const glw::Functions& gl, deUint32 bufferTarget, int numElems) 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<T> result(numElems); 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readDataMapped(gl, bufferTarget, numElems, &result[0]); 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename ArgT, bool res> 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ConstantUnaryPredicate 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const ArgT&) const { return res; } 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Helper for handling simple, one-varying transform feedbacks. 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename VaryingT> 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TransformFeedbackHandler 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct Result 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numPrimitives; 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<VaryingT> varying; 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Result (void) : numPrimitives(-1) {} 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Result (int n, const vector<VaryingT>& v) : numPrimitives(n), varying(v) {} 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TransformFeedbackHandler (const glu::RenderContext& renderCtx, int maxNumVertices); 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Result renderAndGetPrimitives (deUint32 programGL, deUint32 tfPrimTypeGL, int numBindings, const glu::VertexArrayBinding* bindings, int numVertices) const; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::RenderContext& m_renderCtx; 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::TransformFeedback m_tf; 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Buffer m_tfBuffer; 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Query m_tfPrimQuery; 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename AttribType> 3193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTransformFeedbackHandler<AttribType>::TransformFeedbackHandler (const glu::RenderContext& renderCtx, int maxNumVertices) 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_renderCtx (renderCtx) 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_tf (renderCtx) 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_tfBuffer (renderCtx) 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_tfPrimQuery (renderCtx) 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderCtx.getFunctions(); 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Room for 1 extra triangle, to detect if GL returns too many primitives. 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int bufferSize = (maxNumVertices + 3) * (int)sizeof(AttribType); 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, *m_tfBuffer); 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize, DE_NULL, GL_DYNAMIC_READ); 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename AttribType> 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypename TransformFeedbackHandler<AttribType>::Result TransformFeedbackHandler<AttribType>::renderAndGetPrimitives (deUint32 programGL, deUint32 tfPrimTypeGL, int numBindings, const glu::VertexArrayBinding* bindings, int numVertices) const 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tfPrimTypeGL == GL_POINTS || tfPrimTypeGL == GL_LINES || tfPrimTypeGL == GL_TRIANGLES); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_renderCtx.getFunctions(); 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, *m_tf); 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, *m_tfBuffer); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, *m_tfBuffer); 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, *m_tfPrimQuery); 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.beginTransformFeedback(tfPrimTypeGL); 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_renderCtx, programGL, numBindings, bindings, glu::pr::Patches(numVertices)); 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.endTransformFeedback(); 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrimsWritten = (int)getQueryResult(gl, *m_tfPrimQuery); 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return Result(numPrimsWritten, readDataMapped<AttribType>(gl, GL_TRANSFORM_FEEDBACK_BUFFER, numPrimsWritten * numVerticesPerPrimitive(tfPrimTypeGL))); 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SizeLessThan 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const T& a, const T& b) const { return a.size() < b.size(); } 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Predicate functor for comparing structs by their members. 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename Pred, typename T, typename MembT> 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass MemberPred 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MemberPred (MembT T::* membP) : m_membP(membP), m_pred(Pred()) {} 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const T& a, const T& b) const { return m_pred(a.*m_membP, b.*m_membP); } 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry MembT T::* m_membP; 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Pred m_pred; 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Convenience wrapper for MemberPred, because class template arguments aren't deduced based on constructor arguments. 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <template <typename> class Pred, typename T, typename MembT> 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic MemberPred<Pred<MembT>, T, MembT> memberPred (MembT T::* membP) { return MemberPred<Pred<MembT>, T, MembT>(membP); } 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename SeqT, int Size, typename Pred> 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LexCompare 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LexCompare (void) : m_pred(Pred()) {} 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const SeqT& a, const SeqT& b) const 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < Size; i++) 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_pred(a[i], b[i])) 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_pred(b[i], a[i])) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Pred m_pred; 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size> 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VecLexLessThan : public LexCompare<tcu::Vector<float, Size>, Size, std::less<float> > 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum TessPrimitiveType 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSPRIMITIVETYPE_TRIANGLES = 0, 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSPRIMITIVETYPE_QUADS, 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSPRIMITIVETYPE_ISOLINES, 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSPRIMITIVETYPE_LAST 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum SpacingMode 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SPACINGMODE_EQUAL, 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SPACINGMODE_FRACTIONAL_ODD, 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SPACINGMODE_FRACTIONAL_EVEN, 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SPACINGMODE_LAST 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum Winding 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDING_CCW = 0, 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDING_CW, 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDING_LAST 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline const char* getTessPrimitiveTypeShaderName (TessPrimitiveType type) 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: return "triangles"; 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: return "quads"; 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: return "isolines"; 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline const char* getSpacingModeShaderName (SpacingMode mode) 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (mode) 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_EQUAL: return "equal_spacing"; 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_ODD: return "fractional_odd_spacing"; 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_EVEN: return "fractional_even_spacing"; 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline const char* getWindingShaderName (Winding winding) 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (winding) 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case WINDING_CCW: return "ccw"; 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case WINDING_CW: return "cw"; 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode=false) 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + "layout (" + getTessPrimitiveTypeShaderName(primType) 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ", " + getSpacingModeShaderName(spacing) 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ", " + getWindingShaderName(winding) 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (usePointMode ? ", point_mode" : "") 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ") in;\n"; 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, SpacingMode spacing, bool usePointMode=false) 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + "layout (" + getTessPrimitiveTypeShaderName(primType) 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ", " + getSpacingModeShaderName(spacing) 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (usePointMode ? ", point_mode" : "") 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ") in;\n"; 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, Winding winding, bool usePointMode=false) 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + "layout (" + getTessPrimitiveTypeShaderName(primType) 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ", " + getWindingShaderName(winding) 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (usePointMode ? ", point_mode" : "") 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ") in;\n"; 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getTessellationEvaluationInLayoutString (TessPrimitiveType primType, bool usePointMode=false) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + "layout (" + getTessPrimitiveTypeShaderName(primType) 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (usePointMode ? ", point_mode" : "") 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + ") in;\n"; 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline deUint32 outputPrimitiveTypeGL (TessPrimitiveType tessPrimType, bool usePointMode) 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (usePointMode) 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GL_POINTS; 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (tessPrimType) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: return GL_TRIANGLES; 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: return GL_TRIANGLES; 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: return GL_LINES; 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (deUint32)-1; 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int numInnerTessellationLevels (TessPrimitiveType primType) 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primType) 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: return 1; 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: return 2; 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: return 0; 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: DE_ASSERT(false); return -1; 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int numOuterTessellationLevels (TessPrimitiveType primType) 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primType) 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: return 3; 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: return 4; 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: return 2; 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: DE_ASSERT(false); return -1; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string tessellationLevelsString (const float* inner, int numInner, const float* outer, int numOuter) 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numInner >= 0 && numOuter >= 0); 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "inner: " + elemsStr(inner, inner+numInner) + ", outer: " + elemsStr(outer, outer+numOuter); 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string tessellationLevelsString (const float* inner, const float* outer, TessPrimitiveType primType) 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessellationLevelsString(inner, numInnerTessellationLevels(primType), outer, numOuterTessellationLevels(primType)); 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string tessellationLevelsString (const float* inner, const float* outer) 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessellationLevelsString(inner, 2, outer, 4); 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float getClampedTessLevel (SpacingMode mode, float tessLevel) 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (mode) 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_EQUAL: return de::max(1.0f, tessLevel); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_ODD: return de::max(1.0f, tessLevel); 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_EVEN: return de::max(2.0f, tessLevel); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1.0f; 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int getRoundedTessLevel (SpacingMode mode, float clampedTessLevel) 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = (int)deFloatCeil(clampedTessLevel); 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (mode) 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_EQUAL: break; 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_ODD: result += 1 - result % 2; break; 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case SPACINGMODE_FRACTIONAL_EVEN: result += result % 2; break; 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inRange<int>(result, 1, MINIMUM_MAX_TESS_GEN_LEVEL)); 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getClampedRoundedTessLevel (SpacingMode mode, float tessLevel) 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getRoundedTessLevel(mode, getClampedTessLevel(mode, tessLevel)); 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! A description of an outer edge of a triangle, quad or isolines. 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! An outer edge can be described by the index of a u/v/w coordinate 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! and the coordinate's value along that edge. 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct OuterEdgeDescription 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int constantCoordinateIndex; 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float constantCoordinateValueChoices[2]; 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numConstantCoordinateValueChoices; 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription (int i, float c0) : constantCoordinateIndex(i), numConstantCoordinateValueChoices(1) { constantCoordinateValueChoices[0] = c0; } 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription (int i, float c0, float c1) : constantCoordinateIndex(i), numConstantCoordinateValueChoices(2) { constantCoordinateValueChoices[0] = c0; constantCoordinateValueChoices[1] = c1; } 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string description (void) const 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* const coordinateNames[] = { "u", "v", "w" }; 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numConstantCoordinateValueChoices; i++) 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += string() + (i > 0 ? " or " : "") + coordinateNames[constantCoordinateIndex] + "=" + de::toString(constantCoordinateValueChoices[i]); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool contains (const Vec3& v) const 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numConstantCoordinateValueChoices; i++) 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (v[constantCoordinateIndex] == constantCoordinateValueChoices[i]) 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<OuterEdgeDescription> outerEdgeDescriptions (TessPrimitiveType primType) 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const OuterEdgeDescription triangleOuterEdgeDescriptions[3] = 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(0, 0.0f), 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(1, 0.0f), 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(2, 0.0f) 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const OuterEdgeDescription quadOuterEdgeDescriptions[4] = 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(0, 0.0f), 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(1, 0.0f), 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(0, 1.0f), 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(1, 1.0f) 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const OuterEdgeDescription isolinesOuterEdgeDescriptions[1] = 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeDescription(0, 0.0f, 1.0f), 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primType) 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: return arrayToVector(triangleOuterEdgeDescriptions); 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: return arrayToVector(quadOuterEdgeDescriptions); 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: return arrayToVector(isolinesOuterEdgeDescriptions); 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: DE_ASSERT(false); return vector<OuterEdgeDescription>(); 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that u+v+w == 1.0f, or [uvw] + (1.0f-[uvw]) == 1.0f). 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<Vec3> generateReferenceTriangleTessCoords (SpacingMode spacingMode, int inner, int outer0, int outer1, int outer2) 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec3> tessCoords; 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner == 1) 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outer0 == 1 && outer1 == 1 && outer2 == 1) 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(1.0f, 0.0f, 0.0f)); 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(0.0f, 1.0f, 0.0f)); 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(0.0f, 0.0f, 1.0f)); 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessCoords; 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateReferenceTriangleTessCoords(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outer0, outer1, outer2); 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(Vec3( 0.0f, v, 1.0f - v)); } 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(Vec3(1.0f - v, 0.0f, v)); } 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(Vec3( v, 1.0f - v, 0.0f)); } 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInnerTriangles = inner/2; 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++) 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1); 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curInnerTriangleLevel == 0) 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(1.0f/3.0f)); 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float minUVW = (float)(2 * (innerTriangleNdx + 1)) / (float)(3 * inner); 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float maxUVW = 1.0f - 2.0f*minUVW; 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3 corners[3] = 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3(maxUVW, minUVW, minUVW), 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3(minUVW, maxUVW, minUVW), 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3(minUVW, minUVW, maxUVW) 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < curInnerTriangleLevel; i++) 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float f = (float)i / (float)curInnerTriangleLevel; 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 3; j++) 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back((1.0f - f)*corners[j] + f*corners[(j+1)%3]); 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessCoords; 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referenceTriangleNonPointModePrimitiveCount (SpacingMode spacingMode, int inner, int outer0, int outer1, int outer2) 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner == 1) 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outer0 == 1 && outer1 == 1 && outer2 == 1) 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referenceTriangleNonPointModePrimitiveCount(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outer0, outer1, outer2); 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = outer0 + outer1 + outer2; 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInnerTriangles = inner/2; 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++) 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1); 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curInnerTriangleLevel == 1) 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += 4; 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += 2*3*curInnerTriangleLevel; 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f). 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<Vec3> generateReferenceQuadTessCoords (SpacingMode spacingMode, int inner0, int inner1, int outer0, int outer1, int outer2, int outer3) 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec3> tessCoords; 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner0 == 1 || inner1 == 1) 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1) 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(0.0f, 0.0f, 0.0f)); 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(1.0f, 0.0f, 0.0f)); 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(0.0f, 1.0f, 0.0f)); 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3(1.0f, 1.0f, 0.0f)); 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessCoords; 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateReferenceQuadTessCoords(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outer0, outer1, outer2, outer3); 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(Vec3(0.0f, v, 0.0f)); } 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(Vec3(1.0f-v, 0.0f, 0.0f)); } 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(Vec3(1.0f, 1.0f-v, 0.0f)); } 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < outer3; i++) { const float v = (float)i / (float)outer3; tessCoords.push_back(Vec3(v, 1.0f, 0.0f)); } 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int innerVtxY = 0; innerVtxY < inner1-1; innerVtxY++) 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int innerVtxX = 0; innerVtxX < inner0-1; innerVtxX++) 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3((float)(innerVtxX + 1) / (float)inner0, 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (float)(innerVtxY + 1) / (float)inner1, 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.0f)); 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessCoords; 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referenceQuadNonPointModePrimitiveCount (SpacingMode spacingMode, int inner0, int inner1, int outer0, int outer1, int outer2, int outer3) 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec3> tessCoords; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner0 == 1 || inner1 == 1) 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1) 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 2; 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referenceQuadNonPointModePrimitiveCount(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2, 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outer0, outer1, outer2, outer3); 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 2*(inner0-2)*(inner1-2) + 2*(inner0-2) + 2*(inner1-2) + outer0+outer1+outer2+outer3; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note The tessellation coordinates generated by this function could break some of the rules given in the spec (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f). 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<Vec3> generateReferenceIsolineTessCoords (int outer0, int outer1) 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec3> tessCoords; 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < outer0; y++) 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < outer1+1; x++) 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoords.push_back(Vec3((float)x / (float)outer1, 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (float)y / (float)outer0, 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.0f)); 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessCoords; 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referenceIsolineNonPointModePrimitiveCount (int outer0, int outer1) 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return outer0*outer1; 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getClampedRoundedTriangleTessLevels (SpacingMode spacingMode, const float* innerSrc, const float* outerSrc, int* innerDst, int *outerDst) 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry innerDst[0] = getClampedRoundedTessLevel(spacingMode, innerSrc[0]); 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 3; i++) 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]); 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getClampedRoundedQuadTessLevels (SpacingMode spacingMode, const float* innerSrc, const float* outerSrc, int* innerDst, int *outerDst) 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 2; i++) 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry innerDst[i] = getClampedRoundedTessLevel(spacingMode, innerSrc[i]); 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 4; i++) 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]); 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getClampedRoundedIsolineTessLevels (SpacingMode spacingMode, const float* outerSrc, int* outerDst) 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerDst[0] = getClampedRoundedTessLevel(SPACINGMODE_EQUAL, outerSrc[0]); 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerDst[1] = getClampedRoundedTessLevel(spacingMode, outerSrc[1]); 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isPatchDiscarded (TessPrimitiveType primitiveType, const float* outerLevels) 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numOuterLevels = numOuterTessellationLevels(primitiveType); 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numOuterLevels; i++) 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outerLevels[i] <= 0.0f) 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<Vec3> generateReferenceTessCoords (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels) 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isPatchDiscarded(primitiveType, outerLevels)) 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vector<Vec3>(); 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primitiveType) 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner; 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[3]; 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]); 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (spacingMode != SPACINGMODE_EQUAL) 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note For fractional spacing modes, exact results are implementation-defined except in special cases. 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::abs(innerLevels[0] - (float)inner) < 0.001f); 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 3; i++) 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::abs(outerLevels[i] - (float)outer[i]) < 0.001f); 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(inner > 1 || (outer[0] == 1 && outer[1] == 1 && outer[2] == 1)); 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]); 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner[2]; 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[4]; 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]); 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (spacingMode != SPACINGMODE_EQUAL) 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note For fractional spacing modes, exact results are implementation-defined except in special cases. 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 2; i++) 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::abs(innerLevels[i] - (float)inner[i]) < 0.001f); 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 4; i++) 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::abs(outerLevels[i] - (float)outer[i]) < 0.001f); 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((inner[0] > 1 && inner[1] > 1) || (inner[0] == 1 && inner[1] == 1 && outer[0] == 1 && outer[1] == 1 && outer[2] == 1 && outer[3] == 1)); 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]); 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[2]; 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]); 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (spacingMode != SPACINGMODE_EQUAL) 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note For fractional spacing modes, exact results are implementation-defined except in special cases. 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::abs(outerLevels[1] - (float)outer[1]) < 0.001f); 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateReferenceIsolineTessCoords(outer[0], outer[1]); 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vector<Vec3>(); 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referencePointModePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels) 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isPatchDiscarded(primitiveType, outerLevels)) 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primitiveType) 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner; 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[3]; 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]); 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]).size(); 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner[2]; 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[4]; 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]); 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]).size(); 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[2]; 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]); 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)generateReferenceIsolineTessCoords(outer[0], outer[1]).size(); 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referenceNonPointModePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, const float* innerLevels, const float* outerLevels) 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isPatchDiscarded(primitiveType, outerLevels)) 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 0; 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (primitiveType) 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_TRIANGLES: 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner; 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[3]; 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]); 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referenceTriangleNonPointModePrimitiveCount(spacingMode, inner, outer[0], outer[1], outer[2]); 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_QUADS: 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inner[2]; 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[4]; 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]); 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referenceQuadNonPointModePrimitiveCount(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]); 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSPRIMITIVETYPE_ISOLINES: 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outer[2]; 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]); 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referenceIsolineNonPointModePrimitiveCount(outer[0], outer[1]); 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referencePrimitiveCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* innerLevels, const float* outerLevels) 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return usePointMode ? referencePointModePrimitiveCount (primitiveType, spacingMode, innerLevels, outerLevels) 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : referenceNonPointModePrimitiveCount (primitiveType, spacingMode, innerLevels, outerLevels); 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int referenceVertexCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* innerLevels, const float* outerLevels) 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return referencePrimitiveCount(primitiveType, spacingMode, usePointMode, innerLevels, outerLevels) 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * numVerticesPerPrimitive(outputPrimitiveTypeGL(primitiveType, usePointMode)); 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Helper for calling referenceVertexCount multiple times with different tessellation levels. 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! \note Levels contains inner and outer levels, per patch, in order IIOOOO. The full 6 levels must always be present, irrespective of primitiveType. 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int multiplePatchReferenceVertexCount (TessPrimitiveType primitiveType, SpacingMode spacingMode, bool usePointMode, const float* levels, int numPatches) 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = 0; 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPatches; patchNdx++) 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += referenceVertexCount(primitiveType, spacingMode, usePointMode, &levels[6*patchNdx + 0], &levels[6*patchNdx + 2]); 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> generateRandomPatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel, de::Random& rnd) 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> tessLevels(numPatches*6); 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPatches; patchNdx++) 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* const inner = &tessLevels[patchNdx*6 + 0]; 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* const outer = &tessLevels[patchNdx*6 + 2]; 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 2; j++) 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inner[j] = rnd.getFloat(1.0f, 62.0f); 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 4; j++) 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outer[j] = j == constantOuterLevelIndex ? constantOuterLevel : rnd.getFloat(1.0f, 62.0f); 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessLevels; 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void drawPoint (tcu::Surface& dst, int centerX, int centerY, const tcu::RGBA& color, int size) 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int width = dst.getWidth(); 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int height = dst.getHeight(); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(de::inBounds(centerX, 0, width) && de::inBounds(centerY, 0, height)); 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(size > 0); 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int yOff = -((size-1)/2); yOff <= size/2; yOff++) 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int xOff = -((size-1)/2); xOff <= size/2; xOff++) 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int pixX = centerX + xOff; 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int pixY = centerY + yOff; 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::inBounds(pixX, 0, width) && de::inBounds(pixY, 0, height)) 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.setPixel(pixX, pixY, color); 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void drawTessCoordPoint (tcu::Surface& dst, TessPrimitiveType primitiveType, const Vec3& pt, const tcu::RGBA& color, int size) 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note These coordinates should match the description in the log message in TessCoordCase::iterate. 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const Vec2 triangleCorners[3] = 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(0.95f, 0.95f), 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(0.5f, 0.95f - 0.9f*deFloatSqrt(3.0f/4.0f)), 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(0.05f, 0.95f) 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float quadIsolineLDRU[4] = 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.1f, 0.9f, 0.9f, 0.1f 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec2 dstPos = primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? pt.x()*triangleCorners[0] 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + pt.y()*triangleCorners[1] 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + pt.z()*triangleCorners[2] 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : primitiveType == TESSPRIMITIVETYPE_QUADS || 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType == TESSPRIMITIVETYPE_ISOLINES ? Vec2((1.0f - pt.x())*quadIsolineLDRU[0] + pt.x()*quadIsolineLDRU[2], 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (1.0f - pt.y())*quadIsolineLDRU[1] + pt.y()*quadIsolineLDRU[3]) 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Vec2(-1.0f); 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawPoint(dst, (int)(dstPos.x()*dst.getWidth()), (int)(dstPos.y()*dst.getHeight()), color, size); 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void drawTessCoordVisualization (tcu::Surface& dst, TessPrimitiveType primitiveType, const vector<Vec3>& coords) 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int imageWidth = 256; 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int imageHeight = 256; 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst.setSize(imageWidth, imageHeight); 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::clear(dst.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)coords.size(); i++) 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawTessCoordPoint(dst, primitiveType, coords[i], tcu::RGBA::white, 2); 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int binarySearchFirstVec3WithXAtLeast (const vector<Vec3>& sorted, float x) 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3 ref(x, 0.0f, 0.0f); 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>::const_iterator first = std::lower_bound(sorted.begin(), sorted.end(), ref, vec3XLessThan); 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (first == sorted.end()) 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (int)std::distance(sorted.begin(), first); 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T, typename P> 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<T> sorted (const vector<T>& unsorted, P pred) 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<T> result = unsorted; 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(result.begin(), result.end(), pred); 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T> 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<T> sorted (const vector<T>& unsorted) 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<T> result = unsorted; 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(result.begin(), result.end()); 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Check that all points in subset are (approximately) present also in superset. 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool oneWayComparePointSets (TestLog& log, 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface& errorDst, 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessPrimitiveType primitiveType, 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>& subset, 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>& superset, 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* subsetName, 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* supersetName, 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::RGBA& errorColor) 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3> supersetSorted = sorted(superset, vec3XLessThan); 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float epsilon = 0.01f; 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxNumFailurePrints = 5; 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numFailuresDetected = 0; 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int subNdx = 0; subNdx < (int)subset.size(); subNdx++) 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& subPt = subset[subNdx]; 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool matchFound = false; 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Binary search the index of the first point in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range. 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3 matchMin = subPt - epsilon; 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3 matchMax = subPt + epsilon; 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int firstCandidateNdx = binarySearchFirstVec3WithXAtLeast(supersetSorted, matchMin.x()); 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (firstCandidateNdx >= 0) 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compare subPt to all points in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range. 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int superNdx = firstCandidateNdx; superNdx < (int)supersetSorted.size() && supersetSorted[superNdx].x() <= matchMax.x(); superNdx++) 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& superPt = supersetSorted[superNdx]; 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tcu::boolAll(tcu::greaterThanEqual (superPt, matchMin)) && 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::boolAll(tcu::lessThanEqual (superPt, matchMax))) 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry matchFound = true; 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!matchFound) 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numFailuresDetected++; 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numFailuresDetected < maxNumFailurePrints) 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: no matching " << supersetName << " point found for " << subsetName << " point " << subPt << TestLog::EndMessage; 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (numFailuresDetected == maxNumFailurePrints) 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: More errors follow" << TestLog::EndMessage; 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawTessCoordPoint(errorDst, primitiveType, subPt, errorColor, 4); 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numFailuresDetected == 0; 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool compareTessCoords (TestLog& log, TessPrimitiveType primitiveType, const vector<Vec3>& refCoords, const vector<Vec3>& resCoords) 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface refVisual; 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resVisual; 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool success = true; 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawTessCoordVisualization(refVisual, primitiveType, refCoords); 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry drawTessCoordVisualization(resVisual, primitiveType, resCoords); 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that all points in reference also exist in result. 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = oneWayComparePointSets(log, refVisual, primitiveType, refCoords, resCoords, "reference", "result", tcu::RGBA::blue) && success; 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that all points in result also exist in reference. 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = oneWayComparePointSets(log, resVisual, primitiveType, resCoords, refCoords, "result", "reference", tcu::RGBA::red) && success; 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: in the following reference visualization, points that are missing in result point set are blue (if any)" << TestLog::EndMessage 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Image("RefTessCoordVisualization", "Reference tessCoord visualization", refVisual) 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: in the following result visualization, points that are missing in reference point set are red (if any)" << TestLog::EndMessage; 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("ResTessCoordVisualization", "Result tessCoord visualization", resVisual); 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return success; 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace VerifyFractionalSpacingSingleInternal 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Segment 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int index; //!< Index of left coordinate in sortedXCoords. 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float length; 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Segment (void) : index(-1), length(-1.0f) {} 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Segment (int index_, float length_) : index(index_), length(length_) {} 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> lengths (const vector<Segment>& segments) { return members(segments, &Segment::length); } 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Verify fractional spacing conditions for a single line 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Verify that the splitting of an edge (resulting from e.g. an isoline 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * with outer levels { 1.0, tessLevel }) with a given fractional spacing 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * mode fulfills certain conditions given in the spec. 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Note that some conditions can't be checked from just one line 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * (specifically, that the additional segment decreases monotonically 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * length and the requirement that the additional segments be placed 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * identically for identical values of clamped level). 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Therefore, the function stores some values to additionalSegmentLengthDst 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * and additionalSegmentLocationDst that can later be given to 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * verifyFractionalSpacingMultiple(). A negative value in length means that 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * no additional segments are present, i.e. there's just one segment. 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A negative value in location means that the value wasn't determinable, 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * i.e. all segments had same length. 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The values are not stored if false is returned. 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyFractionalSpacingSingle (TestLog& log, SpacingMode spacingMode, float tessLevel, const vector<float>& coords, float& additionalSegmentLengthDst, int& additionalSegmentLocationDst) 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using namespace VerifyFractionalSpacingSingleInternal; 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(spacingMode == SPACINGMODE_FRACTIONAL_ODD || spacingMode == SPACINGMODE_FRACTIONAL_EVEN); 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float clampedLevel = getClampedTessLevel(spacingMode, tessLevel); 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int finalLevel = getRoundedTessLevel(spacingMode, clampedLevel); 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> sortedCoords = sorted(coords); 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string failNote = "Note: tessellation level is " + de::toString(tessLevel) + "\nNote: sorted coordinates are:\n " + containerStr(sortedCoords); 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)coords.size() != finalLevel + 1) 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: number of vertices is " << coords.size() << "; expected " << finalLevel + 1 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " (clamped tessellation level is " << clampedLevel << ")" 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "; final level (clamped level rounded up to " << (spacingMode == SPACINGMODE_FRACTIONAL_EVEN ? "even" : "odd") << ") is " << finalLevel 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " and should equal the number of segments, i.e. number of vertices minus 1" << TestLog::EndMessage 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (sortedCoords[0] != 0.0f || sortedCoords.back() != 1.0f) 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: smallest coordinate should be 0.0 and biggest should be 1.0" << TestLog::EndMessage 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Segment> segments(finalLevel); 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < finalLevel; i++) 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry segments[i] = Segment(i, sortedCoords[i+1] - sortedCoords[i]); 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry failNote += "\nNote: segment lengths are, from left to right:\n " + containerStr(Segment::lengths(segments)); 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Divide segments to two different groups based on length. 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Segment> segmentsA; 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Segment> segmentsB; 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry segmentsA.push_back(segments[0]); 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int segNdx = 1; segNdx < (int)segments.size(); segNdx++) 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float epsilon = 0.001f; 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Segment& seg = segments[segNdx]; 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::abs(seg.length - segmentsA[0].length) < epsilon) 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry segmentsA.push_back(seg); 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (segmentsB.empty() || de::abs(seg.length - segmentsB[0].length) < epsilon) 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry segmentsB.push_back(seg); 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: couldn't divide segments to 2 groups by length; " 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "e.g. segment of length " << seg.length << " isn't approximately equal to either " 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << segmentsA[0].length << " or " << segmentsB[0].length << TestLog::EndMessage 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (clampedLevel == (float)finalLevel) 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // All segments should be of equal length. 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!segmentsA.empty() && !segmentsB.empty()) 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: clamped and final tessellation level are equal, but not all segments are of equal length." << TestLog::EndMessage 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsA.empty() || segmentsB.empty()) // All segments have same length. This is ok. 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLengthDst = segments.size() == 1 ? -1.0f : segments[0].length; 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLocationDst = -1; 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsA.size() != 2 && segmentsB.size() != 2) 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: when dividing the segments to 2 groups by length, neither of the two groups has exactly 2 or 0 segments in it" << TestLog::EndMessage 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // For convenience, arrange so that the 2-segment group is segmentsB. 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsB.size() != 2) 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::swap(segmentsA, segmentsB); 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note For 4-segment lines both segmentsA and segmentsB have 2 segments each. 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Thus, we can't be sure which ones were meant as the additional segments. 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We give the benefit of the doubt by assuming that they're the shorter 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // ones (as they should). 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsA.size() != 2) 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsB[0].length > segmentsA[0].length + 0.001f) 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the two additional segments are longer than the other segments" << TestLog::EndMessage 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1329b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry else 1330b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry { 1331b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry // We have 2 segmentsA and 2 segmentsB, ensure segmentsB has the shorter lengths 1332b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry if (segmentsB[0].length > segmentsA[0].length) 1333b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry std::swap(segmentsA, segmentsB); 1334b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry } 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that the additional segments are placed symmetrically. 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsB[0].index + segmentsB[1].index + 1 != (int)segments.size()) 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the two additional segments aren't placed symmetrically; " 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "one is at index " << segmentsB[0].index << " and other is at index " << segmentsB[1].index 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " (note: the two indexes should sum to " << (int)segments.size()-1 << ", i.e. numberOfSegments-1)" << TestLog::EndMessage 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << failNote << TestLog::EndMessage; 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLengthDst = segmentsB[0].length; 13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (segmentsA.size() != 2) 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLocationDst = de::min(segmentsB[0].index, segmentsB[1].index); 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLocationDst = segmentsB[0].length < segmentsA[0].length - 0.001f ? de::min(segmentsB[0].index, segmentsB[1].index) 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : -1; // \note -1 when can't reliably decide which ones are the additional segments, a or b. 1352b802d8a74b19daa161a07eca2a90bc4620b94021Jarkko Pöyry 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace VerifyFractionalSpacingMultipleInternal 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct LineData 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float tessLevel; 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float additionalSegmentLength; 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int additionalSegmentLocation; 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LineData (float lev, float len, int loc) : tessLevel(lev), additionalSegmentLength(len), additionalSegmentLocation(loc) {} 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Verify fractional spacing conditions between multiple lines 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Verify the fractional spacing conditions that are not checked in 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * verifyFractionalSpacingSingle(). Uses values given by said function 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * as parameters, in addition to the spacing mode and tessellation level. 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool verifyFractionalSpacingMultiple (TestLog& log, SpacingMode spacingMode, const vector<float>& tessLevels, const vector<float>& additionalSegmentLengths, const vector<int>& additionalSegmentLocations) 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using namespace VerifyFractionalSpacingMultipleInternal; 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(spacingMode == SPACINGMODE_FRACTIONAL_ODD || spacingMode == SPACINGMODE_FRACTIONAL_EVEN); 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tessLevels.size() == additionalSegmentLengths.size() && 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessLevels.size() == additionalSegmentLocations.size()); 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<LineData> lineDatas; 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)tessLevels.size(); i++) 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry lineDatas.push_back(LineData(tessLevels[i], additionalSegmentLengths[i], additionalSegmentLocations[i])); 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<LineData> lineDatasSortedByLevel = sorted(lineDatas, memberPred<std::less>(&LineData::tessLevel)); 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that lines with identical clamped tessellation levels have identical additionalSegmentLocation. 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int lineNdx = 1; lineNdx < (int)lineDatasSortedByLevel.size(); lineNdx++) 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LineData& curData = lineDatasSortedByLevel[lineNdx]; 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LineData& prevData = lineDatasSortedByLevel[lineNdx-1]; 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curData.additionalSegmentLocation < 0 || prevData.additionalSegmentLocation < 0) 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Unknown locations, skip. 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (getClampedTessLevel(spacingMode, curData.tessLevel) == getClampedTessLevel(spacingMode, prevData.tessLevel) && 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry curData.additionalSegmentLocation != prevData.additionalSegmentLocation) 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: additional segments not located identically for two edges with identical clamped tessellation levels" << TestLog::EndMessage 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: tessellation levels are " << curData.tessLevel << " and " << prevData.tessLevel 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " (clamped level " << getClampedTessLevel(spacingMode, curData.tessLevel) << ")" 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "; but first additional segments located at indices " 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << curData.additionalSegmentLocation << " and " << prevData.additionalSegmentLocation << ", respectively" << TestLog::EndMessage; 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that, among lines with same clamped rounded tessellation level, additionalSegmentLength is monotonically decreasing with "clampedRoundedTessLevel - clampedTessLevel" (the "fraction"). 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int lineNdx = 1; lineNdx < (int)lineDatasSortedByLevel.size(); lineNdx++) 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LineData& curData = lineDatasSortedByLevel[lineNdx]; 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LineData& prevData = lineDatasSortedByLevel[lineNdx-1]; 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curData.additionalSegmentLength < 0.0f || prevData.additionalSegmentLength < 0.0f) 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; // Unknown segment lengths, skip. 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float curClampedLevel = getClampedTessLevel(spacingMode, curData.tessLevel); 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float prevClampedLevel = getClampedTessLevel(spacingMode, prevData.tessLevel); 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int curFinalLevel = getRoundedTessLevel(spacingMode, curClampedLevel); 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int prevFinalLevel = getRoundedTessLevel(spacingMode, prevClampedLevel); 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curFinalLevel != prevFinalLevel) 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float curFraction = curFinalLevel - curClampedLevel; 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float prevFraction = prevFinalLevel - prevClampedLevel; 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (curData.additionalSegmentLength < prevData.additionalSegmentLength || 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (curClampedLevel == prevClampedLevel && curData.additionalSegmentLength != prevData.additionalSegmentLength)) 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: additional segment length isn't monotonically decreasing with the fraction <n> - <f>, among edges with same final tessellation level" << TestLog::EndMessage 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: <f> stands for the clamped tessellation level and <n> for the final (rounded and clamped) tessellation level" << TestLog::EndMessage 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: two edges have tessellation levels " << prevData.tessLevel << " and " << curData.tessLevel << " respectively" 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", clamped " << prevClampedLevel << " and " << curClampedLevel << ", final " << prevFinalLevel << " and " << curFinalLevel 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "; fractions are " << prevFraction << " and " << curFraction 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", but resulted in segment lengths " << prevData.additionalSegmentLength << " and " << curData.additionalSegmentLength << TestLog::EndMessage; 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Compare triangle sets, ignoring triangle order and vertex order within triangle, and possibly exclude some triangles too. 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename IsTriangleRelevantT> 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool compareTriangleSets (const vector<Vec3>& coordsA, 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>& coordsB, 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log, 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IsTriangleRelevantT& isTriangleRelevant, 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* ignoredTriangleDescription = DE_NULL) 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef tcu::Vector<Vec3, 3> Triangle; 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef LexCompare<Triangle, 3, VecLexLessThan<3> > TriangleLexLessThan; 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef std::set<Triangle, TriangleLexLessThan> TriangleSet; 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(coordsA.size() % 3 == 0 && coordsB.size() % 3 == 0); 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTrianglesA = (int)coordsA.size()/3; 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTrianglesB = (int)coordsB.size()/3; 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleSet trianglesA; 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleSet trianglesB; 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int aOrB = 0; aOrB < 2; aOrB++) 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>& coords = aOrB == 0 ? coordsA : coordsB; 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTriangles = aOrB == 0 ? numTrianglesA : numTrianglesB; 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleSet& triangles = aOrB == 0 ? trianglesA : trianglesB; 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int triNdx = 0; triNdx < numTriangles; triNdx++) 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Triangle triangle(coords[3*triNdx + 0], 14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry coords[3*triNdx + 1], 14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry coords[3*triNdx + 2]); 14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isTriangleRelevant(triangle.getPtr())) 14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(triangle.getPtr(), triangle.getPtr()+3, VecLexLessThan<3>()); 14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry triangles.insert(triangle); 14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleSet::const_iterator aIt = trianglesA.begin(); 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TriangleSet::const_iterator bIt = trianglesB.begin(); 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (aIt != trianglesA.end() || bIt != trianglesB.end()) 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool aEnd = aIt == trianglesA.end(); 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool bEnd = bIt == trianglesB.end(); 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (aEnd || bEnd || *aIt != *bIt) 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: triangle sets in two cases are not equal (when ignoring triangle and vertex order" 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (ignoredTriangleDescription == DE_NULL ? "" : string() + ", and " + ignoredTriangleDescription) << ")" << TestLog::EndMessage; 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!aEnd && (bEnd || TriangleLexLessThan()(*aIt, *bIt))) 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: e.g. triangle " << *aIt << " exists for first case but not for second" << TestLog::EndMessage; 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: e.g. triangle " << *bIt << " exists for second case but not for first" << TestLog::EndMessage; 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++aIt; 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++bIt; 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool compareTriangleSets (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, TestLog& log) 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, log, ConstantUnaryPredicate<const Vec3*, true>()); 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void checkExtensionSupport (Context& context, const char* extName) 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!context.getContextInfo().isExtensionSupported(extName)) 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError(string(extName) + " not supported"); 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void checkTessellationSupport (Context& context) 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkExtensionSupport(context, "GL_EXT_tessellation_shader"); 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Draw primitives with shared edges and check that no cracks are visible at the shared edges. 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CommonEdgeCase : public TestCase 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseType 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_BASIC = 0, //!< Order patch vertices such that when two patches share a vertex, it's at the same index for both. 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_PRECISE, //!< Vertex indices don't match like for CASETYPE_BASIC, but other measures are taken, using the 'precise' qualifier. 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_LAST 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CommonEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, CaseType caseType) 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primitiveType) 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseType (caseType) 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES || m_primitiveType == TESSPRIMITIVETYPE_QUADS); 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseType m_caseType; 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CommonEdgeCase::init (void) 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_caseType == CASETYPE_PRECISE) 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkExtensionSupport(m_context, "GL_EXT_gpu_shader5"); 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_v_position;\n" 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_tessParam;\n" 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 in_tc_position;\n" 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_tessParam;\n" 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_position = in_v_position;\n" 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_tessParam = in_v_tessParam;\n" 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + string(m_caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") + 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + string(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "3" : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? "4" : DE_NULL) + ") out;\n" 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_tc_position[];\n" 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_tessParam[];\n" 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 in_te_position[];\n" 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRECISE ? "precise gl_TessLevelOuter;\n\n" : "") + 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n" 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 5.0;\n" 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 5.0;\n" 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[2]);\n" 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[0]);\n" 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[1]);\n" 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[2]);\n" 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[0]);\n" 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[3] + in_tc_tessParam[1]);\n" 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[3]);\n" 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + string(m_caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") + 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing) + 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_te_position[];\n" 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 in_f_color;\n" 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRECISE ? "precise gl_Position;\n\n" : "") + 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = gl_TessCoord.x*in_te_position[0] + gl_TessCoord.y*in_te_position[1] + gl_TessCoord.z*in_te_position[2];\n" 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float f = sqrt(3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z))) * 0.5 + 0.5;\n" 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(gl_TessCoord*f, 1.0);\n" 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string() 16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_BASIC ? 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0]\n" 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1]\n" 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[2]\n" 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[3];\n" 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PRECISE ? 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 a = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0];\n" 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 b = ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1];\n" 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 c = (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[2];\n" 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 d = ( gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[3];\n" 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = a+b+c+d;\n" 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float f = sqrt(1.0 - 2.0 * max(abs(gl_TessCoord.x - 0.5), abs(gl_TessCoord.y - 0.5)))*0.5 + 0.5;\n" 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(0.1, gl_TessCoord.xy*f, 1.0);\n" 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Offset the position slightly, based on the parity of the bits in the float representation.\n" 16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // This is done to detect possible small differences in edge vertex positions between patches.\n" 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " uvec2 bits = floatBitsToUint(pos);\n" 16698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry " uint numBits = 0u;\n" 16708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry " for (uint i = 0u; i < 32u; i++)\n" 16718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry " numBits += ((bits[0] >> i) & 1u) + ((bits[1] >> i) & 1u);\n" 16728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry " pos += float(numBits&1u)*0.04;\n" 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 in_f_color;\n" 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid CommonEdgeCase::deinit (void) 16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryCommonEdgeCase::IterateResult CommonEdgeCase::iterate (void) 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int gridWidth = 4; 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int gridHeight = 4; 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVertices = (gridWidth+1)*(gridHeight+1); 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numIndices = gridWidth*gridHeight * (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3*2 : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 : -1); 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPosCompsPerVertex = 2; 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int totalNumPosComps = numPosCompsPerVertex*numVertices; 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> gridPosComps; 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> gridTessParams; 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint16> gridIndices; 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridPosComps.reserve(totalNumPosComps); 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridTessParams.reserve(numVertices); 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridIndices.reserve(numIndices); 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < gridHeight+1; i++) 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < gridWidth+1; j++) 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridPosComps.push_back(-1.0f + 2.0f * ((float)j + 0.5f) / (float)(gridWidth+1)); 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridPosComps.push_back(-1.0f + 2.0f * ((float)i + 0.5f) / (float)(gridHeight+1)); 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridTessParams.push_back((float)(i*(gridWidth+1) + j) / (float)(numVertices-1)); 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Generate patch vertex indices. 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note If CASETYPE_BASIC, the vertices are ordered such that when multiple 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // triangles/quads share a vertex, it's at the same index for everyone. 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < gridHeight; i++) 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < gridWidth; j++) 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int corners[4] = 17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (i+0)*(gridWidth+1) + j+0, 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (i+0)*(gridWidth+1) + j+1, 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (i+1)*(gridWidth+1) + j+0, 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (i+1)*(gridWidth+1) + j+1 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int secondTriangleVertexIndexOffset = m_caseType == CASETYPE_BASIC ? 0 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PRECISE ? 1 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : -1; 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(secondTriangleVertexIndexOffset != -1); 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int k = 0; k < 3; k++) 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridIndices.push_back(corners[(k+0 + i + (2-j%3)) % 3]); 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int k = 0; k < 3; k++) 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridIndices.push_back(corners[(k+2 + i + (2-j%3) + secondTriangleVertexIndexOffset) % 3 + 1]); 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < gridHeight; i++) 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < gridWidth; j++) 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note The vertices are ordered such that when multiple quads 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // share a vertices, it's at the same index for everyone. 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int m = 0; m < 2; m++) 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int n = 0; n < 2; n++) 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridIndices.push_back((i+(i+m)%2)*(gridWidth+1) + j+(j+n)%2); 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if(m_caseType == CASETYPE_PRECISE && (i+j) % 2 == 0) 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::reverse(gridIndices.begin() + (gridIndices.size() - 4), 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gridIndices.begin() + gridIndices.size()); 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)gridPosComps.size() == totalNumPosComps); 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)gridTessParams.size() == numVertices); 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)gridIndices.size() == numIndices); 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 : -1); 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding attrBindings[] = 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_position", numPosCompsPerVertex, numVertices, 0, &gridPosComps[0]), 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_tessParam", 1, numVertices, 0, &gridTessParams[0]) 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(renderCtx, programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0], 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Patches((int)gridIndices.size(), &gridIndices[0])); 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered Image", rendered) 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: coloring is done to clarify the positioning and orientation of the " 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "triangles" : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? "quads" : DE_NULL) 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "; the color of a vertex corresponds to the index of that vertex in the patch" 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_caseType == CASETYPE_BASIC) 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: each shared vertex has the same index among the primitives it belongs to" << TestLog::EndMessage; 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_caseType == CASETYPE_PRECISE) 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: the 'precise' qualifier is used to avoid cracks between primitives" << TestLog::EndMessage; 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ad-hoc result verification - check that a certain rectangle in the image contains no black pixels. 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int startX = (int)(0.15f * (float)rendered.getWidth()); 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int endX = (int)(0.85f * (float)rendered.getWidth()); 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int startY = (int)(0.15f * (float)rendered.getHeight()); 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int endY = (int)(0.85f * (float)rendered.getHeight()); 18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = startY; y < endY; y++) 18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = startX; x < endX; x++) 18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::RGBA pixel = rendered.getPixel(x, y); 18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pixel.getRed() == 0 && pixel.getGreen() == 0 && pixel.getBlue() == 0) 18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: there seem to be cracks in the rendered result" << TestLog::EndMessage 18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: pixel with zero r, g and b channels found at " << tcu::IVec2(x, y) << TestLog::EndMessage; 18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Success: there seem to be no cracks in the rendered result" << TestLog::EndMessage; 18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Check tessellation coordinates (read with transform feedback). 18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TessCoordCase : public TestCase 18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessCoordCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing) 18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primitiveType) 18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct TessLevels 18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float inner[2]; 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float outer[4]; 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<TessLevels> genTessLevelCases (void) const; 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessCoordCase::init (void) 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner0;\n" 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner1;\n" 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter0;\n" 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter1;\n" 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter2;\n" 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter3;\n" 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = u_tessLevelInner0;\n" 19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = u_tessLevelInner1;\n" 19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = u_tessLevelOuter0;\n" 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_tessLevelOuter1;\n" 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = u_tessLevelOuter2;\n" 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = u_tessLevelOuter3;\n" 19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, true) + 19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec3 out_te_tessCoord;\n" 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord;\n" 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*1.6 - 0.8, 0.0, 1.0);\n" 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0);\n" 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessCoordCase::deinit (void) 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<TessCoordCase::TessLevels> TessCoordCase::genTessLevelCases (void) const 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const TessLevels rawTessLevelCases[] = 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 63.0f, 24.0f }, { 15.0f, 42.0f, 10.0f, 12.0f } }, 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 3.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 4.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 2.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.0f, 6.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 1.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.0f, 1.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.2f, 1.6f }, { 2.9f, 3.4f, 1.5f, 4.1f } } 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_spacing == SPACINGMODE_EQUAL) 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return vector<TessLevels>(DE_ARRAY_BEGIN(rawTessLevelCases), DE_ARRAY_END(rawTessLevelCases)); 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<TessLevels> result; 19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.reserve(DE_LENGTH_OF_ARRAY(rawTessLevelCases)); 19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(rawTessLevelCases); tessLevelCaseNdx++) 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessLevels curTessLevelCase = rawTessLevelCases[tessLevelCaseNdx]; 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* const inner = &curTessLevelCase.inner[0]; 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float* const outer = &curTessLevelCase.outer[0]; 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 2; j++) inner[j] = (float)getClampedRoundedTessLevel(m_spacing, inner[j]); 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 4; j++) outer[j] = (float)getClampedRoundedTessLevel(m_spacing, outer[j]); 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f) 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner[0] == 1.0f) 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inner[0] = (float)getClampedRoundedTessLevel(m_spacing, inner[0] + 0.1f); 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f || outer[3] > 1.0f) 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner[0] == 1.0f) inner[0] = (float)getClampedRoundedTessLevel(m_spacing, inner[0] + 0.1f); 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (inner[1] == 1.0f) inner[1] = (float)getClampedRoundedTessLevel(m_spacing, inner[1] + 0.1f); 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(curTessLevelCase); 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)result.size() == DE_LENGTH_OF_ARRAY(rawTessLevelCases)); 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessCoordCase::IterateResult TessCoordCase::iterate (void) 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelInner0Loc = gl.getUniformLocation(programGL, "u_tessLevelInner0"); 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelInner1Loc = gl.getUniformLocation(programGL, "u_tessLevelInner1"); 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelOuter0Loc = gl.getUniformLocation(programGL, "u_tessLevelOuter0"); 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelOuter1Loc = gl.getUniformLocation(programGL, "u_tessLevelOuter1"); 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelOuter2Loc = gl.getUniformLocation(programGL, "u_tessLevelOuter2"); 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelOuter3Loc = gl.getUniformLocation(programGL, "u_tessLevelOuter3"); 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<TessLevels> tessLevelCases = genTessLevelCases(); 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<vector<Vec3> > caseReferences (tessLevelCases.size()); 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)tessLevelCases.size(); i++) 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseReferences[i] = generateReferenceTessCoords(m_primitiveType, m_spacing, &tessLevelCases[i].inner[0], &tessLevelCases[i].outer[0]); 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxNumVertices = (int)std::max_element(caseReferences.begin(), caseReferences.end(), SizeLessThan<vector<Vec3> >())->size(); 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler (m_context.getRenderContext(), maxNumVertices); 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool success = true; 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++) 20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const innerLevels = &tessLevelCases[tessLevelCaseNdx].inner[0]; 20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const outerLevels = &tessLevelCases[tessLevelCaseNdx].outer[0]; 20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Tessellation levels: " << tessellationLevelsString(innerLevels, outerLevels, m_primitiveType) << TestLog::EndMessage; 20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelInner0Loc, innerLevels[0]); 20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelInner1Loc, innerLevels[1]); 20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelOuter0Loc, outerLevels[0]); 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelOuter1Loc, outerLevels[1]); 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelOuter2Loc, outerLevels[2]); 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelOuter3Loc, outerLevels[3]); 20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed"); 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3>& tessCoordsRef = caseReferences[tessLevelCaseNdx]; 20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, GL_POINTS, 0, DE_NULL, 1); 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tfResult.numPrimitives != (int)tessCoordsRef.size()) 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be " 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tfResult.numPrimitives << ", reference value is " << tessCoordsRef.size() 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " (logging further info anyway)" << TestLog::EndMessage; 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = false; 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be " << tfResult.numPrimitives << TestLog::EndMessage; 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: in the following visualization(s), the u=1, v=1, w=1 corners are at the right, top, and left corners, respectively" << TestLog::EndMessage; 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS || m_primitiveType == TESSPRIMITIVETYPE_ISOLINES) 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: in the following visualization(s), u and v coordinate go left-to-right and bottom-to-top, respectively" << TestLog::EndMessage; 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = compareTessCoords(log, m_primitiveType, tessCoordsRef, tfResult.varying) && success; 20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "All OK" << TestLog::EndMessage; 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Invalid tessellation coordinates"); 20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Check validity of fractional spacing modes. Draws a single isoline, reads tesscoords with transform feedback. 20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FractionalSpacingModeCase : public TestCase 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FractionalSpacingModeCase (Context& context, const char* name, const char* description, SpacingMode spacing) 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_spacing == SPACINGMODE_FRACTIONAL_EVEN || m_spacing == SPACINGMODE_FRACTIONAL_ODD); 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> genTessLevelCases (void); 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FractionalSpacingModeCase::init (void) 21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter1;\n" 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 1.0;\n" 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_tessLevelOuter1;\n" 21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_ISOLINES, m_spacing, true) + 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float out_te_tessCoord;\n" 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord.x;\n" 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*1.6 - 0.8, 0.0, 1.0);\n" 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0);\n" 21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FractionalSpacingModeCase::deinit (void) 21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> FractionalSpacingModeCase::genTessLevelCases (void) 21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> result; 21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ranges [7.0 .. 8.0), [8.0 .. 9.0) and [9.0 .. 10.0) 21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float rangeStarts[] = { 7.0f, 8.0f, 9.0f }; 21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSamplesPerRange = 10; 21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(rangeStarts); rangeNdx++) 21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numSamplesPerRange; i++) 21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(rangeStarts[rangeNdx] + (float)i/(float)numSamplesPerRange); 21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // 0.3, 1.3, 2.3, ... , 62.3 21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i <= 62; i++) 21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back((float)i + 0.3f); 21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFractionalSpacingModeCase::IterateResult FractionalSpacingModeCase::iterate (void) 21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<float> TFHandler; 21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessLevelOuter1Loc = gl.getUniformLocation(programGL, "u_tessLevelOuter1"); 22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Second outer tessellation levels. 22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> tessLevelCases = genTessLevelCases(); 22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maxNumVertices = 1 + getClampedRoundedTessLevel(m_spacing, *std::max_element(tessLevelCases.begin(), tessLevelCases.end())); 22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> additionalSegmentLengths; 22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<int> additionalSegmentLocations; 22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler (m_context.getRenderContext(), maxNumVertices); 22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool success = true; 22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++) 22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float outerLevel1 = tessLevelCases[tessLevelCaseNdx]; 22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(tessLevelOuter1Loc, outerLevel1); 22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Setup failed"); 22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, GL_POINTS, 0, DE_NULL, 1); 22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float additionalSegmentLength; 22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int additionalSegmentLocation; 22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = verifyFractionalSpacingSingle(log, m_spacing, outerLevel1, tfResult.varying, 22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLength, additionalSegmentLocation); 22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLengths.push_back(additionalSegmentLength); 22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry additionalSegmentLocations.push_back(additionalSegmentLocation); 22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (success) 22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = verifyFractionalSpacingMultiple(log, m_spacing, tessLevelCases, additionalSegmentLengths, additionalSegmentLocations); 22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Invalid tessellation coordinates"); 22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Base class for a case with one input attribute (in_v_position) and optionally a TCS; tests with a couple of different sets of tessellation levels. 22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BasicVariousTessLevelsPosAttrCase : public TestCase 22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicVariousTessLevelsPosAttrCase (Context& context, 22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name, 22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description, 22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessPrimitiveType primitiveType, 22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SpacingMode spacing, 22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* referenceImagePathPrefix) 22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primitiveType) 22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePathPrefix (referenceImagePathPrefix) 22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual const glu::ProgramSources makeSources (TessPrimitiveType, SpacingMode, const char* vtxOutPosAttrName) const = DE_NULL; 22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePathPrefix; 22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BasicVariousTessLevelsPosAttrCase::init (void) 22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources = makeSources(m_primitiveType, m_spacing, "in_tc_position"); 22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].empty()); 22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TessellationControlSource( "#version 310 es\n" 22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + string(m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "3" : "4") + ") out;\n" 22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_tc_position[];\n" 22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 in_te_position[];\n" 23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner0;\n" 23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner1;\n" 23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter0;\n" 23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter1;\n" 23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter2;\n" 23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter3;\n" 23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n" 23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = u_tessLevelInner0;\n" 23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = u_tessLevelInner1;\n" 23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = u_tessLevelOuter0;\n" 23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_tessLevelOuter1;\n" 23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = u_tessLevelOuter2;\n" 23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = u_tessLevelOuter3;\n" 23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"); 23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), sources)); 23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BasicVariousTessLevelsPosAttrCase::deinit (void) 23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBasicVariousTessLevelsPosAttrCase::IterateResult BasicVariousTessLevelsPosAttrCase::iterate (void) 23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float inner[2]; 23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float outer[4]; 23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } tessLevelCases[] = 23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 9.0f, 9.0f }, { 9.0f, 9.0f, 9.0f, 9.0f } }, 23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 8.0f, 11.0f }, { 13.0f, 15.0f, 18.0f, 21.0f } }, 23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 17.0f, 14.0f }, { 3.0f, 6.0f, 9.0f, 12.0f } } 23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int patchSize = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_ISOLINES ? 4 23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : -1; 23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, patchSize); 23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(tessLevelCases); tessLevelCaseNdx++) 23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float innerLevels[2]; 23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float outerLevels[4]; 23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < DE_LENGTH_OF_ARRAY(innerLevels); i++) 23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry innerLevels[i] = (float)getClampedRoundedTessLevel(m_spacing, tessLevelCases[tessLevelCaseNdx].inner[i]); 23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < DE_LENGTH_OF_ARRAY(outerLevels); i++) 23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerLevels[i] = (float)getClampedRoundedTessLevel(m_spacing, tessLevelCases[tessLevelCaseNdx].outer[i]); 23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Tessellation levels: " << tessellationLevelsString(&innerLevels[0], &outerLevels[0], m_primitiveType) << TestLog::EndMessage; 23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelInner0"), innerLevels[0]); 23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelInner1"), innerLevels[1]); 23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter0"), outerLevels[0]); 23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter1"), outerLevels[1]); 23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter2"), outerLevels[2]); 23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_tessLevelOuter3"), outerLevels[3]); 23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec2> positions; 23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.reserve(4); 23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2( 0.8f, 0.6f)); 23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2( 0.0f, -0.786f)); 23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2(-0.8f, 0.6f)); 23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS || m_primitiveType == TESSPRIMITIVETYPE_ISOLINES) 23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2(-0.8f, -0.8f)); 23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2( 0.8f, -0.8f)); 24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2(-0.8f, 0.8f)); 24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry positions.push_back(Vec2( 0.8f, 0.8f)); 24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((int)positions.size() == patchSize); 24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding attrBindings[] = 24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_position", 2, (int)positions.size(), 0, &positions[0].x()) 24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0], 24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Patches(patchSize)); 24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePathPrefix + "_" + de::toString(tessLevelCaseNdx) + ".png"); 24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.002f, tcu::COMPARE_LOG_RESULT); 24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test that there are no obvious gaps in the triangulation of a tessellated triangle or quad. 24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BasicTriangleFillCoverCase : public BasicVariousTessLevelsPosAttrCase 24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicTriangleFillCoverCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, const char* referenceImagePathPrefix) 24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : BasicVariousTessLevelsPosAttrCase (context, name, description, primitiveType, spacing, referenceImagePathPrefix) 24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 24467f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry void init (void) 24477f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry { 24487f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry checkExtensionSupport(m_context, "GL_EXT_gpu_shader5"); 24497f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry BasicVariousTessLevelsPosAttrCase::init(); 24507f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry } 24517f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry 24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const 24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::ProgramSources() 24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_v_position;\n" 24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 " + string(vtxOutPosAttrName) + ";\n" 24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + vtxOutPosAttrName + " = in_v_position;\n" 24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 24687f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry "#extension GL_EXT_gpu_shader5 : require\n" 24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(primitiveType, spacing) + 24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_te_position[];\n" 24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24747f553a46ae44aeab4277e572bf61fb59b29f1208Jarkko Pöyry "precise gl_Position;\n" 24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n" 24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner0 = in_te_position[0];\n" 24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner1 = in_te_position[1];\n" 24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner2 = in_te_position[2];\n" 24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n" 24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 fromCenter = pos - (corner0 + corner1 + corner2) / 3.0;\n" 24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float f = (1.0 - length(fromCenter)) * (1.5 - d);\n" 24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n" 24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : primitiveType == TESSPRIMITIVETYPE_QUADS ? 24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner0 = in_te_position[0];\n" 24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner1 = in_te_position[1];\n" 24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner2 = in_te_position[2];\n" 24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner3 = in_te_position[3];\n" 24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n" 24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n" 24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*corner2\n" 24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*( gl_TessCoord.y)*corner3;\n" 24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float d = 2.0 * min(abs(gl_TessCoord.x-0.5), abs(gl_TessCoord.y-0.5));\n" 24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 fromCenter = pos - (corner0 + corner1 + corner2 + corner3) / 4.0;\n" 24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float f = (1.0 - length(fromCenter)) * sqrt(1.7 - d);\n" 25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " pos += 0.75 * f * fromCenter / (length(fromCenter) + 0.3);\n" 25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0);\n" 25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"); 25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Check that there are no obvious overlaps in the triangulation of a tessellated triangle or quad. 25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BasicTriangleFillNonOverlapCase : public BasicVariousTessLevelsPosAttrCase 25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicTriangleFillNonOverlapCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, SpacingMode spacing, const char* referenceImagePathPrefix) 25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : BasicVariousTessLevelsPosAttrCase (context, name, description, primitiveType, spacing, referenceImagePathPrefix) 25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const 25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::ProgramSources() 25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_v_position;\n" 25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 " + string(vtxOutPosAttrName) + ";\n" 25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + vtxOutPosAttrName + " = in_v_position;\n" 25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(primitiveType, spacing) + 25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_te_position[];\n" 25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 in_f_color;\n" 25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner0;\n" 25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelInner1;\n" 25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner0 = in_te_position[0];\n" 25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner1 = in_te_position[1];\n" 25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner2 = in_te_position[2];\n" 25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = corner0*gl_TessCoord.x + corner1*gl_TessCoord.y + corner2*gl_TessCoord.z;\n" 25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int numConcentricTriangles = int(round(u_tessLevelInner0)) / 2 + 1;\n" 25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float d = 3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z));\n" 25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phase = int(d*float(numConcentricTriangles)) % 3;\n" 25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n" 25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n" 25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(0.0, 0.0, 1.0, 1.0);\n" 25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : primitiveType == TESSPRIMITIVETYPE_QUADS ? 25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner0 = in_te_position[0];\n" 25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner1 = in_te_position[1];\n" 25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner2 = in_te_position[2];\n" 25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner3 = in_te_position[3];\n" 25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n" 25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n" 25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*corner2\n" 25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*( gl_TessCoord.y)*corner3;\n" 25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phaseX = int(round((0.5 - abs(gl_TessCoord.x-0.5)) * u_tessLevelInner0));\n" 25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phaseY = int(round((0.5 - abs(gl_TessCoord.y-0.5)) * u_tessLevelInner1));\n" 25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phase = min(phaseX, phaseY) % 3;\n" 25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n" 25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n" 25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(0.0, 0.0, 1.0, 1.0);\n" 25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 in_f_color;\n" 25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"); 25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Basic isolines rendering case. 26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IsolinesRenderCase : public BasicVariousTessLevelsPosAttrCase 26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsolinesRenderCase (Context& context, const char* name, const char* description, SpacingMode spacing, const char* referenceImagePathPrefix) 26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : BasicVariousTessLevelsPosAttrCase (context, name, description, TESSPRIMITIVETYPE_ISOLINES, spacing, referenceImagePathPrefix) 26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ProgramSources makeSources (TessPrimitiveType primitiveType, SpacingMode spacing, const char* vtxOutPosAttrName) const 26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_ISOLINES); 26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(primitiveType); 26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return glu::ProgramSources() 26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_v_position;\n" 26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec2 " + string(vtxOutPosAttrName) + ";\n" 26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + vtxOutPosAttrName + " = in_v_position;\n" 26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_ISOLINES, spacing) + 26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec2 in_te_position[];\n" 26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 in_f_color;\n" 26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter0;\n" 26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform mediump float u_tessLevelOuter1;\n" 26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner0 = in_te_position[0];\n" 26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner1 = in_te_position[1];\n" 26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner2 = in_te_position[2];\n" 26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 corner3 = in_te_position[3];\n" 26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner0\n" 26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*corner1\n" 26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*corner2\n" 26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + ( gl_TessCoord.x)*( gl_TessCoord.y)*corner3;\n" 26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " pos.y += 0.15*sin(gl_TessCoord.x*10.0);\n" 26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(pos, 0.0, 1.0);\n" 26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phaseX = int(round(gl_TessCoord.x*u_tessLevelOuter1));\n" 26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phaseY = int(round(gl_TessCoord.y*u_tessLevelOuter0));\n" 26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp int phase = (phaseX + phaseY) % 3;\n" 26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = phase == 0 ? vec4(1.0, 0.0, 0.0, 1.0)\n" 26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : phase == 1 ? vec4(0.0, 1.0, 0.0, 1.0)\n" 26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(0.0, 0.0, 1.0, 1.0);\n" 26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 in_f_color;\n" 26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"); 26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test the "cw" and "ccw" TES input layout qualifiers. 26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass WindingCase : public TestCase 26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WindingCase (Context& context, const char* name, const char* description, TessPrimitiveType primitiveType, Winding winding) 26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primitiveType) 26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_winding (winding) 26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 64; 26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding m_winding; 26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid WindingCase::init (void) 26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 5.0;\n" 27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 5.0;\n" 27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 5.0;\n" 27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 5.0;\n" 27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 5.0;\n" 27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 5.0;\n" 27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_winding) + 27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*2.0 - 1.0, 0.0, 1.0);\n" 27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0);\n" 27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid WindingCase::deinit (void) 27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryWindingCase::IterateResult WindingCase::iterate (void) 27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (renderCtx); 27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool success = true; 27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_CULL_FACE); 27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Face culling enabled" << TestLog::EndMessage; 27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int frontFaceWinding = 0; frontFaceWinding < WINDING_LAST; frontFaceWinding++) 27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Setting glFrontFace(" << (frontFaceWinding == WINDING_CW ? "GL_CW" : "GL_CCW") << ")" << TestLog::EndMessage; 27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.frontFace(frontFaceWinding == WINDING_CW ? GL_CW : GL_CCW); 27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 1); 27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered Image", rendered); 27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int totalNumPixels = rendered.getWidth()*rendered.getHeight(); 27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int badPixelTolerance = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 5*de::max(rendered.getWidth(), rendered.getHeight()) : 0; 27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numWhitePixels = 0; 27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numRedPixels = 0; 27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < rendered.getHeight(); y++) 27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < rendered.getWidth(); x++) 27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numWhitePixels += rendered.getPixel(x, y) == tcu::RGBA::white ? 1 : 0; 28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numRedPixels += rendered.getPixel(x, y) == tcu::RGBA::red ? 1 : 0; 28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numWhitePixels + numRedPixels <= totalNumPixels); 28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: got " << numWhitePixels << " white and " << numRedPixels << " red pixels" << TestLog::EndMessage; 28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (totalNumPixels - numWhitePixels - numRedPixels > badPixelTolerance) 28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: Got " << totalNumPixels - numWhitePixels - numRedPixels << " other than white or red pixels (maximum tolerance " << badPixelTolerance << ")" << TestLog::EndMessage; 28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = false; 28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((Winding)frontFaceWinding == m_winding) 28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::abs(numWhitePixels - totalNumPixels/2) > badPixelTolerance) 28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: wrong number of white pixels; expected approximately " << totalNumPixels/2 << TestLog::EndMessage; 28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = false; 28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numWhitePixels != totalNumPixels) 28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected only white pixels (full-viewport quad)" << TestLog::EndMessage; 28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = false; 28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numWhitePixels != 0) 28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected only red pixels (everything culled)" << TestLog::EndMessage; 28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry success = false; 28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image verification failed"); 28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test potentially differing input and output patch sizes. 28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PatchVertexCountCase : public TestCase 28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PatchVertexCountCase (Context& context, const char* name, const char* description, int inputPatchSize, int outputPatchSize, const char* referenceImagePath) 28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_inputPatchSize (inputPatchSize) 28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_outputPatchSize (outputPatchSize) 28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePath (referenceImagePath) 28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_inputPatchSize; 28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_outputPatchSize; 28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePath; 28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PatchVertexCountCase::init (void) 28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string inSizeStr = de::toString(m_inputPatchSize); 28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string outSizeStr = de::toString(m_outputPatchSize); 28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + outSizeStr + ") out;\n" 29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_te_attr[];\n" 29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID*" + inSizeStr + "/" + outSizeStr + "];\n" 29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 5.0;\n" 29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 5.0;\n" 29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 5.0;\n" 29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 5.0;\n" 29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 5.0;\n" 29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 5.0;\n" 29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) + 29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_te_attr[];\n" 29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 in_f_color;\n" 29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float x = gl_TessCoord.x*2.0 - 1.0;\n" 29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float y = gl_TessCoord.y - in_te_attr[int(round(gl_TessCoord.x*float(" + outSizeStr + "-1)))];\n" 29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(x, y, 0.0, 1.0);\n" 29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(1.0);\n" 29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 in_f_color;\n" 29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PatchVertexCountCase::deinit (void) 29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPatchVertexCountCase::IterateResult PatchVertexCountCase::iterate (void) 29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: input patch size is " << m_inputPatchSize << ", output patch size is " << m_outputPatchSize << TestLog::EndMessage; 29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> attributeData; 29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData.reserve(m_inputPatchSize); 29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < m_inputPatchSize; i++) 29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float f = (float)i / (float)(m_inputPatchSize-1); 29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData.push_back(f*f); 29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, m_inputPatchSize); 29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding attrBindings[] = 29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0]) 29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0], 29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Patches(m_inputPatchSize)); 29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePath); 30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT); 30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed"); 30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Test per-patch inputs/outputs. 30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PerPatchDataCase : public TestCase 30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseType 30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_PRIMITIVE_ID_TCS = 0, 30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_PRIMITIVE_ID_TES, 30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_PATCH_VERTICES_IN_TCS, 30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_PATCH_VERTICES_IN_TES, 30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_INNER0_TES, 30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_INNER1_TES, 30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_OUTER0_TES, 30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_OUTER1_TES, 30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_OUTER2_TES, 30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TESS_LEVEL_OUTER3_TES, 30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_LAST 30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PerPatchDataCase (Context& context, const char* name, const char* description, CaseType caseType, const char* referenceImagePath) 30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseType (caseType) 30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePath (caseTypeUsesRefImageFromFile(caseType) ? referenceImagePath : "") 30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(caseTypeUsesRefImageFromFile(caseType) == (referenceImagePath != DE_NULL)); 30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getCaseTypeName (CaseType); 30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getCaseTypeDescription (CaseType); 30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static bool caseTypeUsesRefImageFromFile (CaseType); 30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int INPUT_PATCH_SIZE; 30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int OUTPUT_PATCH_SIZE; 30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseType m_caseType; 30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePath; 30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst int PerPatchDataCase::INPUT_PATCH_SIZE = 10; 30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst int PerPatchDataCase::OUTPUT_PATCH_SIZE = 5; 30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* PerPatchDataCase::getCaseTypeName (CaseType type) 30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TCS: return "primitive_id_tcs"; 30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TES: return "primitive_id_tes"; 30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PATCH_VERTICES_IN_TCS: return "patch_vertices_in_tcs"; 30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PATCH_VERTICES_IN_TES: return "patch_vertices_in_tes"; 30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_INNER0_TES: return "tess_level_inner_0_tes"; 30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_INNER1_TES: return "tess_level_inner_1_tes"; 30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER0_TES: return "tess_level_outer_0_tes"; 30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER1_TES: return "tess_level_outer_1_tes"; 30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER2_TES: return "tess_level_outer_2_tes"; 30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER3_TES: return "tess_level_outer_3_tes"; 30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* PerPatchDataCase::getCaseTypeDescription (CaseType type) 30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TCS: return "Read gl_PrimitiveID in TCS and pass it as patch output to TES"; 30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TES: return "Read gl_PrimitiveID in TES"; 30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PATCH_VERTICES_IN_TCS: return "Read gl_PatchVerticesIn in TCS and pass it as patch output to TES"; 30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PATCH_VERTICES_IN_TES: return "Read gl_PatchVerticesIn in TES"; 30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_INNER0_TES: return "Read gl_TessLevelInner[0] in TES"; 30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_INNER1_TES: return "Read gl_TessLevelInner[1] in TES"; 30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER0_TES: return "Read gl_TessLevelOuter[0] in TES"; 30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER1_TES: return "Read gl_TessLevelOuter[1] in TES"; 30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER2_TES: return "Read gl_TessLevelOuter[2] in TES"; 30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TESS_LEVEL_OUTER3_TES: return "Read gl_TessLevelOuter[3] in TES"; 30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool PerPatchDataCase::caseTypeUsesRefImageFromFile (CaseType type) 31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TCS: 31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_PRIMITIVE_ID_TES: 31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PerPatchDataCase::init (void) 31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(OUTPUT_PATCH_SIZE < INPUT_PATCH_SIZE); 31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string inSizeStr = de::toString(INPUT_PATCH_SIZE); 31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string outSizeStr = de::toString(OUTPUT_PATCH_SIZE); 31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + outSizeStr + ") out;\n" 31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_te_attr[];\n" 31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS ? "patch out mediump int in_te_primitiveIDFromTCS;\n" 31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS ? "patch out mediump int in_te_patchVerticesInFromTCS;\n" 31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : "") + 31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];\n" 31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS ? "\tin_te_primitiveIDFromTCS = gl_PrimitiveID;\n" 31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS ? "\tin_te_patchVerticesInFromTCS = gl_PatchVerticesIn;\n" 31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : "") + 31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 9.0;\n" 31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 8.0;\n" 31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 7.0;\n" 31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 6.0;\n" 31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 5.0;\n" 31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 4.0;\n" 31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) + 31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_te_attr[];\n" 31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS ? "patch in mediump int in_te_primitiveIDFromTCS;\n" 31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS ? "patch in mediump int in_te_patchVerticesInFromTCS;\n" 31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : string()) + 31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump vec4 in_f_color;\n" 31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform highp float u_xScale;\n" 31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float x = (gl_TessCoord.x*u_xScale + in_te_attr[0]) * 2.0 - 1.0;\n" 31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float y = gl_TessCoord.y*2.0 - 1.0;\n" 31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(x, y, 0.0, 1.0);\n" 31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_caseType == CASETYPE_PRIMITIVE_ID_TCS ? "\tbool ok = in_te_primitiveIDFromTCS == 3;\n" 31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PRIMITIVE_ID_TES ? "\tbool ok = gl_PrimitiveID == 3;\n" 31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PATCH_VERTICES_IN_TCS ? "\tbool ok = in_te_patchVerticesInFromTCS == " + inSizeStr + ";\n" 31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_PATCH_VERTICES_IN_TES ? "\tbool ok = gl_PatchVerticesIn == " + outSizeStr + ";\n" 31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_INNER0_TES ? "\tbool ok = abs(gl_TessLevelInner[0] - 9.0) < 0.1f;\n" 31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_INNER1_TES ? "\tbool ok = abs(gl_TessLevelInner[1] - 8.0) < 0.1f;\n" 31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_OUTER0_TES ? "\tbool ok = abs(gl_TessLevelOuter[0] - 7.0) < 0.1f;\n" 31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_OUTER1_TES ? "\tbool ok = abs(gl_TessLevelOuter[1] - 6.0) < 0.1f;\n" 31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_OUTER2_TES ? "\tbool ok = abs(gl_TessLevelOuter[2] - 5.0) < 0.1f;\n" 31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_caseType == CASETYPE_TESS_LEVEL_OUTER3_TES ? "\tbool ok = abs(gl_TessLevelOuter[3] - 4.0) < 0.1f;\n" 31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = ok ? vec4(1.0) : vec4(vec3(0.0), 1.0);\n" 31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 in_f_color;\n" 32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PerPatchDataCase::deinit (void) 32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPerPatchDataCase::IterateResult PerPatchDataCase::iterate (void) 32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: input patch size is " << INPUT_PATCH_SIZE << ", output patch size is " << OUTPUT_PATCH_SIZE << TestLog::EndMessage; 32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrimitives = m_caseType == CASETYPE_PRIMITIVE_ID_TCS || m_caseType == CASETYPE_PRIMITIVE_ID_TES ? 8 : 1; 32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> attributeData; 32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData.reserve(numPrimitives*INPUT_PATCH_SIZE); 32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numPrimitives; i++) 32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData.push_back((float)i / (float)numPrimitives); 32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < INPUT_PATCH_SIZE-1; j++) 32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData.push_back(0.0f); 32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, INPUT_PATCH_SIZE); 32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(gl.getUniformLocation(programGL, "u_xScale"), 1.0f / (float)numPrimitives); 32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding attrBindings[] = 32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0]) 32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0], 32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Patches(numPrimitives*INPUT_PATCH_SIZE)); 32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_caseType == CASETYPE_PRIMITIVE_ID_TCS || m_caseType == CASETYPE_PRIMITIVE_ID_TES) 32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(caseTypeUsesRefImageFromFile(m_caseType)); 32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePath); 32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT); 32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed"); 32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!caseTypeUsesRefImageFromFile(m_caseType)); 32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered Image", rendered); 32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < rendered.getHeight(); y++) 32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < rendered.getWidth(); x++) 32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (rendered.getPixel(x, y) != tcu::RGBA::white) 32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected all white pixels" << TestLog::EndMessage; 32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Basic barrier() usage in TCS. 32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass BarrierCase : public TestCase 32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BarrierCase (Context& context, const char* name, const char* description, const char* referenceImagePath) 32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePath (referenceImagePath) 33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int NUM_VERTICES; 33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePath; 33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> m_program; 33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst int BarrierCase::NUM_VERTICES = 32; 33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BarrierCase::init (void) 33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string numVertsStr = de::toString(NUM_VERTICES); 33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + numVertsStr + ") out;\n" 33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_te_attr[];\n" 33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp float in_te_patchAttr;\n" 33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_attr[gl_InvocationID] = in_tc_attr[gl_InvocationID];\n" 33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_patchAttr = 0.0f;\n" 33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (gl_InvocationID == 5)\n" 33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_patchAttr = float(gl_InvocationID)*0.1;\n" 33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float temp = in_te_patchAttr + in_te_attr[gl_InvocationID];\n" 33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (gl_InvocationID == " + numVertsStr + "-1)\n" 33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_patchAttr = float(gl_InvocationID);\n" 33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_attr[gl_InvocationID] = temp;\n" 33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " temp = temp + in_te_attr[(gl_InvocationID+1) % " + numVertsStr + "];\n" 33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " barrier();\n" 33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_attr[gl_InvocationID] = 0.25*temp;\n" 33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 32.0;\n" 33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 32.0;\n" 33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 32.0;\n" 33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 32.0;\n" 33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 32.0;\n" 33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 32.0;\n" 33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_QUADS) + 33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_te_attr[];\n" 33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp float in_te_patchAttr;\n" 33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_f_blue;\n" 33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float x = gl_TessCoord.x*2.0 - 1.0;\n" 33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp float y = gl_TessCoord.y - in_te_attr[int(round(gl_TessCoord.x*float(" + numVertsStr + "-1)))];\n" 33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(x, y, 0.0, 1.0);\n" 33918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry " in_f_blue = abs(in_te_patchAttr - float(" + numVertsStr + "-1));\n" 33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_f_blue;\n" 33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0, 0.0, in_f_blue, 1.0);\n" 34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid BarrierCase::deinit (void) 34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryBarrierCase::IterateResult BarrierCase::iterate (void) 34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> attributeData(NUM_VERTICES); 34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < NUM_VERTICES; i++) 34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry attributeData[i] = (float)i / (float)(NUM_VERTICES-1); 34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, NUM_VERTICES); 34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding attrBindings[] = 34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::va::Float("in_v_attr", 1, (int)attributeData.size(), 0, &attributeData[0]) 34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), programGL, DE_LENGTH_OF_ARRAY(attrBindings), &attrBindings[0], 34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Patches(NUM_VERTICES)); 34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Draw failed"); 34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface rendered = getPixels(renderCtx, viewport); 34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePath); 34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), rendered.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT); 34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(success ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, success ? "Pass" : "Image comparison failed"); 34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Base class for testing invariance of entire primitive set 34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws two patches with identical tessellation levels and compares the 34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * results. Repeats the same with other programs that are only different 34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * in irrelevant ways; compares the results between these two programs. 34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Also potentially compares to results produced by different tessellation 34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * levels (see e.g. invariance rule #6). 34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Furthermore, repeats the above with multiple different tessellation 34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * value sets. 34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The manner of primitive set comparison is defined by subclass. E.g. 34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * case for invariance rule #1 tests that same vertices come out, in same 34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * order; rule #5 only requires that the same triangles are output, but 34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * not necessarily in the same order. 34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PrimitiveSetInvarianceCase : public TestCase 34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum WindingUsage 34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDINGUSAGE_CCW = 0, 34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDINGUSAGE_CW, 34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDINGUSAGE_VARY, 34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry WINDINGUSAGE_LAST 34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrimitiveSetInvarianceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, bool usePointMode, WindingUsage windingUsage) 34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_usePointMode (usePointMode) 34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_windingUsage (windingUsage) 34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct TessLevels 34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float inner[2]; 35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float outer[4]; 35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string description (void) const { return tessellationLevelsString(&inner[0], &outer[0]); } 35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 35043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct LevelCase 35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<TessLevels> levels; 35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int mem; //!< Subclass-defined arbitrary piece of data, for type of the levelcase, if needed. Passed to compare(). 35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LevelCase (const TessLevels& lev) : levels(vector<TessLevels>(1, lev)), mem(0) {} 35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LevelCase (void) : mem(0) {} 35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual vector<LevelCase> genTessLevelCases (void) const; 35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int levelCaseMem) const = 0; 35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct Program 35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Winding winding; 35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> program; 35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Program (Winding w, const SharedPtr<const ShaderProgram>& prog) : winding(w), program(prog) {} 35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string description (void) const { return string() + "winding mode " + getWindingShaderName(winding); }; 35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_usePointMode; 35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const WindingUsage m_windingUsage; 35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Program> m_programs; 35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<PrimitiveSetInvarianceCase::LevelCase> PrimitiveSetInvarianceCase::genTessLevelCases (void) const 35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const TessLevels basicTessLevelCases[] = 35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 63.0f, 24.0f }, { 15.0f, 42.0f, 10.0f, 12.0f } }, 35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 3.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 4.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 2.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.0f, 6.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 1.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.0f, 1.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { { 5.2f, 1.6f }, { 2.9f, 3.4f, 1.5f, 4.1f } } 35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<LevelCase> result; 35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < DE_LENGTH_OF_ARRAY(basicTessLevelCases); i++) 35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(LevelCase(basicTessLevelCases[i])); 35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd(123); 35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < 10; i++) 35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessLevels levels; 35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.inner); j++) 35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.inner[j] = rnd.getFloat(1.0f, 16.0f); 35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.outer); j++) 35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.outer[j] = rnd.getFloat(1.0f, 16.0f); 35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(LevelCase(levels)); 35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PrimitiveSetInvarianceCase::init (void) 35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numDifferentConstantExprCases = 2; 35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Winding> windings; 35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_windingUsage) 35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case WINDINGUSAGE_CCW: windings.push_back(WINDING_CCW); break; 35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case WINDINGUSAGE_CW: windings.push_back(WINDING_CW); break; 35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case WINDINGUSAGE_VARY: windings.push_back(WINDING_CCW); 35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry windings.push_back(WINDING_CW); break; 35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: DE_ASSERT(false); 35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int constantExprCaseNdx = 0; constantExprCaseNdx < numDifferentConstantExprCases; constantExprCaseNdx++) 35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int windingCaseNdx = 0; windingCaseNdx < (int)windings.size(); windingCaseNdx++) 35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string floatLit01 = de::floatToString(10.0f / (float)(constantExprCaseNdx + 10), 2); 35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int programNdx = (int)m_programs.size(); 35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_programs.push_back(Program(windings[windingCaseNdx], 35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + de::toString(constantExprCaseNdx+1) + ") out;\n" 36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp float in_te_positionOffset;\n" 36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_positionOffset = in_tc_attr[6];\n" 36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, windings[windingCaseNdx], m_usePointMode) + 36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp float in_te_positionOffset;\n" 36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "invariant out highp vec3 out_te_tessCoord;\n" 36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*" + floatLit01 + " - in_te_positionOffset + float(gl_PrimitiveID)*0.1, 0.0, 1.0);\n" 36423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(" + floatLit01 + ");\n" 36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord;\n" 36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))))); 36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program" + de::toString(programNdx), "Program " + de::toString(programNdx)); 36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx == 0 || !m_programs.back().program->isOk()) 36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_programs.back().program; 36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_programs.back().program->isOk()) 36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx > 0) 36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Note: program " << programNdx << " is similar to above, except some constants are different, and: " << m_programs.back().description() << TestLog::EndMessage; 36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PrimitiveSetInvarianceCase::deinit (void) 36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_programs.clear(); 36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPrimitiveSetInvarianceCase::IterateResult PrimitiveSetInvarianceCase::iterate (void) 36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<LevelCase> tessLevelCases = genTessLevelCases(); 36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<vector<int> > primitiveCounts; 36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxNumPrimitives = -1; 36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int caseNdx = 0; caseNdx < (int)tessLevelCases.size(); caseNdx++) 36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveCounts.push_back(vector<int>()); 36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)tessLevelCases[caseNdx].levels.size(); i++) 36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 36983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int primCount = referencePrimitiveCount(m_primitiveType, m_spacing, m_usePointMode, 36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry &tessLevelCases[caseNdx].levels[i].inner[0], &tessLevelCases[caseNdx].levels[i].outer[0]); 37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveCounts.back().push_back(primCount); 37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxNumPrimitives = de::max(maxNumPrimitives, primCount); 37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 primitiveTypeGL = outputPrimitiveTypeGL(m_primitiveType, m_usePointMode); 37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler transformFeedback (m_context.getRenderContext(), 2*maxNumPrimitives*numVerticesPerPrimitive(primitiveTypeGL)); 37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 7); 37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < (int)tessLevelCases.size(); tessLevelCaseNdx++) 37123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const LevelCase& levelCase = tessLevelCases[tessLevelCaseNdx]; 37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Vec3> firstPrimVertices; 37153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string tessLevelsStr; 37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)levelCase.levels.size(); i++) 37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessLevelsStr += (levelCase.levels.size() > 1 ? "\n" : "") + levelCase.levels[i].description(); 37203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Tessellation level sets: " << tessLevelsStr << TestLog::EndMessage; 37213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int subTessLevelCaseNdx = 0; subTessLevelCaseNdx < (int)levelCase.levels.size(); subTessLevelCaseNdx++) 37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessLevels& tessLevels = levelCase.levels[subTessLevelCaseNdx]; 37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float (&inner)[2] = tessLevels.inner; 37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float (&outer)[4] = tessLevels.outer; 37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float attribute[2*7] = { inner[0], inner[1], outer[0], outer[1], outer[2], outer[3], 0.0f, 37293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry inner[0], inner[1], outer[0], outer[1], outer[2], outer[3], 0.5f }; 37303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, DE_LENGTH_OF_ARRAY(attribute), 0, &attribute[0]) }; 37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int programNdx = 0; programNdx < (int)m_programs.size(); programNdx++) 37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_programs[programNdx].program->getProgram(); 37353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 37363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = transformFeedback.renderAndGetPrimitives(programGL, primitiveTypeGL, DE_LENGTH_OF_ARRAY(bindings), &bindings[0], DE_LENGTH_OF_ARRAY(attribute)); 37373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tfResult.numPrimitives != 2*primitiveCounts[tessLevelCaseNdx][subTessLevelCaseNdx]) 37393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: GL reported GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN to be " 37413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tfResult.numPrimitives << ", reference value is " << 2*primitiveCounts[tessLevelCaseNdx][subTessLevelCaseNdx] 37423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 37433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives"); 37453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 37463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int half = (int)tfResult.varying.size()/2; 37503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<Vec3> prim0Vertices = vector<Vec3>(tfResult.varying.begin(), tfResult.varying.begin() + half); 37513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3* const prim1Vertices = &tfResult.varying[half]; 37523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vtxNdx = 0; vtxNdx < (int)prim0Vertices.size(); vtxNdx++) 37543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (prim0Vertices[vtxNdx] != prim1Vertices[vtxNdx]) 37563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: tessellation coordinate at index " << vtxNdx << " differs between two primitives drawn in one draw call" << TestLog::EndMessage 37583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: the coordinate is " << prim0Vertices[vtxNdx] << " for the first primitive and " << prim1Vertices[vtxNdx] << " for the second" << TestLog::EndMessage 37593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: tessellation levels for both primitives were: " << tessellationLevelsString(&inner[0], &outer[0]) << TestLog::EndMessage; 37603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives"); 37613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 37623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx == 0 && subTessLevelCaseNdx == 0) 37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry firstPrimVertices = prim0Vertices; 37673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 37683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool compareOk = compare(firstPrimVertices, prim0Vertices, levelCase.mem); 37703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!compareOk) 37713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 37723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: comparison of tessellation coordinates failed; comparison was made between following cases:\n" 37733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case A: program 0, tessellation levels: " << tessLevelCases[tessLevelCaseNdx].levels[0].description() << "\n" 37743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case B: program " << programNdx << ", tessellation levels: " << tessLevels.description() << TestLog::EndMessage; 37753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of primitives"); 37763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 37773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 37833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 37853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 37863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #1 37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 37913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the sequence of primitives input to the TES only depends on 37923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the tessellation levels, tessellation mode, spacing mode, winding, and 37933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * point mode. 37943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 37953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvariantPrimitiveSetCase : public PrimitiveSetInvarianceCase 37963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 37973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 37983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvariantPrimitiveSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 37993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PrimitiveSetInvarianceCase(context, name, description, primType, spacing, usePointMode, winding == WINDING_CCW ? WINDINGUSAGE_CCW 38003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : winding == WINDING_CW ? WINDINGUSAGE_CW 38013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : WINDINGUSAGE_LAST) 38023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 38063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const 38073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vtxNdx = 0; vtxNdx < (int)coordsA.size(); vtxNdx++) 38093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (coordsA[vtxNdx] != coordsB[vtxNdx]) 38113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Failure: tessellation coordinate at index " << vtxNdx << " differs between two programs" << TestLog::EndMessage 38133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: the coordinate is " << coordsA[vtxNdx] << " for the first program and " << coordsB[vtxNdx] << " for the other" << TestLog::EndMessage; 38143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 38153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 38183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #2 38233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 38243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the set of vertices along an outer edge of a quad or triangle 38253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * only depends on that edge's tessellation level, and spacing. 38263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 38273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * For each (outer) edge in the quad or triangle, draw multiple patches 38283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * with identical tessellation levels for that outer edge but with 38293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * different values for the other outer edges; compare, among the 38303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * primitives, the vertices generated for that outer edge. Repeat with 38313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * different programs, using different winding etc. settings. Compare 38323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the edge's vertices between different programs. 38333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 38343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvariantOuterEdgeCase : public TestCase 38353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 38373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvariantOuterEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing) 38383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 38393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 38403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 38413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS); 38433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 38443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 38463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 38473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 38483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 38503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct Program 38513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Winding winding; 38533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool usePointMode; 38543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram> program; 38553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Program (Winding w, bool point, const SharedPtr<const ShaderProgram>& prog) : winding(w), usePointMode(point), program(prog) {} 38573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string description (void) const { return string() + "winding mode " + getWindingShaderName(winding) + ", " + (usePointMode ? "" : "don't ") + "use point mode"; }; 38593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 38603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel); 38623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 38643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 38663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 38673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Program> m_programs; 38693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 38703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> InvariantOuterEdgeCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel) 38723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd(123); 38743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd); 38753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 38763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InvariantOuterEdgeCase::init (void) 38783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 38793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 38803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 38813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int windingI = 0; windingI < WINDING_LAST; windingI++) 38833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding winding = (Winding)windingI; 38853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++) 38873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 38883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool usePointMode = usePointModeI != 0; 38893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int programNdx = (int)m_programs.size(); 38903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string floatLit01 = de::floatToString(10.0f / (float)(programNdx + 10), 2); 38913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 38923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_programs.push_back(Program(winding, usePointMode, 38933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 38943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 38953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 38963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 38973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 38983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 38993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 39003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 39013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 39023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 39033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 39053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 39063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = " + de::toString(programNdx+1) + ") out;\n" 39083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 39103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 39123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 39133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 39143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 39153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 39173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 39183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 39193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 39203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 39213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 39233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 39243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, winding, usePointMode) + 39263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 39283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "invariant out highp vec3 out_te_tessCoord;\n" 39293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 39313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 39323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*" + floatLit01 + " - float(gl_PrimitiveID)*0.05, 0.0, 1.0);\n" 39333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(" + floatLit01 + ");\n" 39343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord;\n" 39353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 39363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 39383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 39403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 39423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 39433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 39443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 39453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 39463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 39473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 39493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))))); 39503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Program" + de::toString(programNdx), "Program " + de::toString(programNdx)); 39533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx == 0 || !m_programs.back().program->isOk()) 39553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_programs.back().program; 39563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_programs.back().program->isOk()) 39583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 39593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx > 0) 39613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Note: program " << programNdx << " is similar to above, except some constants are different, and: " << m_programs.back().description() << TestLog::EndMessage; 39623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InvariantOuterEdgeCase::deinit (void) 39683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_programs.clear(); 39703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 39713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvariantOuterEdgeCase::IterateResult InvariantOuterEdgeCase::iterate (void) 39733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 39743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 39753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 39773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 39783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 39793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 39803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float singleOuterEdgeLevels[] = { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f }; 39823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPatchesPerDrawCall = 10; 39833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<OuterEdgeDescription> edgeDescriptions = outerEdgeDescriptions(m_primitiveType); 39843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once. 39873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxNumVerticesInDrawCall = 0; 39883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(numPatchesPerDrawCall, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels)); 39903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++) 39923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxNumVerticesInDrawCall = de::max(maxNumVerticesInDrawCall, 39933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry multiplePatchReferenceVertexCount(m_primitiveType, m_spacing, usePointModeI != 0, &patchTessLevels[0], numPatchesPerDrawCall)); 39943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 39953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 39973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall); 39983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 39993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 40003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 6); 40013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++) 40033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const OuterEdgeDescription& edgeDesc = edgeDescriptions[outerEdgeIndex]; 40053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++) 40073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set; 40093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(numPatchesPerDrawCall, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 40113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) }; 40123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set firstOuterEdgeVertices; // Vertices of the outer edge of the first patch of the first program's draw call; used for comparison with other patches. 40133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx] 40153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " for the " << edgeDesc.description() << " edge, and with various levels for other edges, and with all programs" << TestLog::EndMessage; 40163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int programNdx = 0; programNdx < (int)m_programs.size(); programNdx++) 40183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Program& program = m_programs[programNdx]; 40203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = program.program->getProgram(); 40213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 40233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, program.usePointMode), 40263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size()); 40273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refNumVertices = multiplePatchReferenceVertexCount(m_primitiveType, m_spacing, program.usePointMode, &patchTessLevels[0], numPatchesPerDrawCall); 40283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVerticesRead = 0; 40293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)tfResult.varying.size() != refNumVertices) 40313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is " 40333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage 40343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: rendered " << numPatchesPerDrawCall 40353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " patches in one draw call; tessellation levels for each patch are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n" 40363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << containerStr(patchTessLevels, 6) << TestLog::EndMessage; 40373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 40393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 40403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check the vertices of each patch. 40433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPatchesPerDrawCall; patchNdx++) 40453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const innerLevels = &patchTessLevels[6*patchNdx + 0]; 40473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const outerLevels = &patchTessLevels[6*patchNdx + 2]; 40483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int patchNumVertices = referenceVertexCount(m_primitiveType, m_spacing, program.usePointMode, innerLevels, outerLevels); 40493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set outerEdgeVertices; 40503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We're interested in just the vertices on the current outer edge. 40523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for(int vtxNdx = numVerticesRead; vtxNdx < numVerticesRead + patchNumVertices; vtxNdx++) 40533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& vtx = tfResult.varying[vtxNdx]; 40553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (edgeDesc.contains(vtx)) 40563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerEdgeVertices.insert(tfResult.varying[vtxNdx]); 40573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that the outer edge contains an appropriate number of vertices. 40603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refNumVerticesOnOuterEdge = 1 + getClampedRoundedTessLevel(m_spacing, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 40623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)outerEdgeVertices.size() != refNumVerticesOnOuterEdge) 40643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the number of vertices on outer edge is " << outerEdgeVertices.size() 40663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", expected " << refNumVerticesOnOuterEdge << TestLog::EndMessage 40673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: vertices on the outer edge are:\n" << containerStr(outerEdgeVertices, 5, 0) << TestLog::EndMessage 40683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: the following parameters were used: " << program.description() 40693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", tessellation levels: " << tessellationLevelsString(innerLevels, outerLevels) << TestLog::EndMessage; 40703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 40713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 40723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compare the vertices to those of the first patch (unless this is the first patch). 40763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (programNdx == 0 && patchNdx == 0) 40783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry firstOuterEdgeVertices = outerEdgeVertices; 40793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 40803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (firstOuterEdgeVertices != outerEdgeVertices) 40823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 40833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: vertices generated for the edge differ between the following cases:\n" 40843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case A: " << m_programs[0].description() << ", tessellation levels: " 40853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tessellationLevelsString(&patchTessLevels[0], &patchTessLevels[2]) << "\n" 40863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case B: " << program.description() << ", tessellation levels: " 40873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tessellationLevelsString(innerLevels, outerLevels) << TestLog::EndMessage; 40883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: resulting vertices for the edge for the cases were:\n" 40903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case A: " << containerStr(firstOuterEdgeVertices, 5, 14) << "\n" 40913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " - case B: " << containerStr(outerEdgeVertices, 5, 14) << TestLog::EndMessage; 40923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 40943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 40953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 40973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 40983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVerticesRead += patchNumVertices; 40993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(numVerticesRead == (int)tfResult.varying.size()); 41023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 41103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 41113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 41123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 41143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #3 41153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 41163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the vertices along an outer edge are placed symmetrically. 41173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 41183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draw multiple patches with different tessellation levels and different 41193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * point_mode, winding etc. Before outputting tesscoords with TF, mirror 41203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the vertices in the TES such that every vertex on an outer edge - 41213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * except the possible middle vertex - should be duplicated in the output. 41223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Check that appropriate duplicates exist. 41233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 41243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass SymmetricOuterEdgeCase : public TestCase 41253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 41273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SymmetricOuterEdgeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 41283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 41293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 41303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 41313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_winding (winding) 41323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_usePointMode (usePointMode) 41333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 41343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 41353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 41373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 41383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 41393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 41413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel); 41423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 41443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 41463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 41473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding m_winding; 41483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_usePointMode; 41493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 41513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 41523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> SymmetricOuterEdgeCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel) 41543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd(123); 41563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd); 41573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 41583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SymmetricOuterEdgeCase::init (void) 41603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 41613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 41623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 41633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 41653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 41663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 41683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 41693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 41713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 41723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 41733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 41743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 41763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 41773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 41793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 41813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 41833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 41843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 41853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 41863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 41883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 41893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 41903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 41913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 41923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 41933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 41943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 41953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) + 41973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 41983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 41993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 out_te_tessCoord_isMirrored;\n" 42003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 42013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 42023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 42033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 42043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float x = gl_TessCoord.x;\n" 42053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float y = gl_TessCoord.y;\n" 42063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float z = gl_TessCoord.z;\n" 42073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n" 42083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord_isMirrored = z == 0.0 && x > 0.5 && x != 1.0 ? vec4(1.0-x, 1.0-y, 0.0, 1.0)\n" 42093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : y == 0.0 && z > 0.5 && z != 1.0 ? vec4(1.0-x, 0.0, 1.0-z, 1.0)\n" 42103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : x == 0.0 && y > 0.5 && y != 1.0 ? vec4( 0.0, 1.0-y, 1.0-z, 1.0)\n" 42113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(x, y, z, 0.0);\n" 42123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 42133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float x = gl_TessCoord.x;\n" 42143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float y = gl_TessCoord.y;\n" 42153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n" 42163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord_isMirrored = (x == 0.0 || x == 1.0) && y > 0.5 && y != 1.0 ? vec4( x, 1.0-y, 0.0, 1.0)\n" 42173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : (y == 0.0 || y == 1.0) && x > 0.5 && x != 1.0 ? vec4(1.0-x, y, 0.0, 1.0)\n" 42183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(x, y, 0.0, 0.0);\n" 42193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_ISOLINES ? 42203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float x = gl_TessCoord.x;\n" 42213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float y = gl_TessCoord.y;\n" 42223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Mirror one half of each outer edge onto the other half\n" 42233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord_isMirrored = (x == 0.0 || x == 1.0) && y > 0.5 ? vec4(x, 1.0-y, 0.0, 1.0)\n" 42243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(x, y, 0.0, 0.0f);\n" 42253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) + 42263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 42273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n" 42283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(1.0);\n" 42293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 42303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 42323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 42333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 42343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 42353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 42363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 42373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 42383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 42393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 42403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 42413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord_isMirrored") 42433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 42443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 42463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 42473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 42483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 42493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid SymmetricOuterEdgeCase::deinit (void) 42513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 42523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 42533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 42543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42553c827367444ee418f129b2c238299f49d3264554Jarkko PoyrySymmetricOuterEdgeCase::IterateResult SymmetricOuterEdgeCase::iterate (void) 42563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 42573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec4> TFHandler; 42583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 42603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 42613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 42623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 42633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float singleOuterEdgeLevels[] = { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f }; 42653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<OuterEdgeDescription> edgeDescriptions = outerEdgeDescriptions(m_primitiveType); 42663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once. 42693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxNumVerticesInDrawCall; 42703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(1, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels)); 42723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxNumVerticesInDrawCall = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]); 42733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 42743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall); 42773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 42793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 6); 42803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++) 42823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const OuterEdgeDescription& edgeDesc = edgeDescriptions[outerEdgeIndex]; 42843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++) 42863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set; 42883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(1, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 42903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) }; 42913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx] 42933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " for the " << edgeDesc.description() << " edge, and with various levels for other edges" << TestLog::EndMessage; 42943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 42963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 42973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 42983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 42993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode), 43023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size()); 43033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refNumVertices = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]); 43043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)tfResult.varying.size() != refNumVertices) 43063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is " 43083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage 43093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: rendered 1 patch, tessellation levels are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n" 43103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << containerStr(patchTessLevels, 6) << TestLog::EndMessage; 43113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 43133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 43143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check the vertices. 43173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set nonMirroredEdgeVertices; 43203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set mirroredEdgeVertices; 43213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We're interested in just the vertices on the current outer edge. 43233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for(int vtxNdx = 0; vtxNdx < refNumVertices; vtxNdx++) 43243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& vtx = tfResult.varying[vtxNdx].swizzle(0,1,2); 43263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (edgeDesc.contains(vtx)) 43273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Ignore the middle vertex of the outer edge, as it's exactly at the mirroring point; 43293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // for isolines, also ignore (0, 0) and (1, 0) because there's no mirrored counterpart for them. 43303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES && vtx == tcu::select(Vec3(0.0f), Vec3(0.5f), singleTrueMask<3>(edgeDesc.constantCoordinateIndex))) 43313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 43323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_QUADS && vtx.swizzle(0,1) == tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]), 43333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec2(0.5f), 43343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry singleTrueMask<2>(edgeDesc.constantCoordinateIndex))) 43353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 43363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_ISOLINES && (vtx == Vec3(0.0f, 0.5f, 0.0f) || vtx == Vec3(1.0f, 0.5f, 0.0f) || 43373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx == Vec3(0.0f, 0.0f, 0.0f) || vtx == Vec3(1.0f, 0.0f, 0.0f))) 43383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 43393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMirrored = tfResult.varying[vtxNdx].w() > 0.5f; 43413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMirrored) 43423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry mirroredEdgeVertices.insert(vtx); 43433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 43443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nonMirroredEdgeVertices.insert(vtx); 43453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType != TESSPRIMITIVETYPE_ISOLINES) 43493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that both endpoints are present. Note that endpoints aren't mirrored by the shader, since they belong to more than one edge. 43513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3 endpointA; 43533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3 endpointB; 43543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 43563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry endpointA = tcu::select(Vec3(1.0f), Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 1) % 3)); 43583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry endpointB = tcu::select(Vec3(1.0f), Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 2) % 3)); 43593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 43613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry endpointA.xy() = tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]), Vec2(0.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex)); 43633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry endpointB.xy() = tcu::select(Vec2(edgeDesc.constantCoordinateValueChoices[0]), Vec2(1.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex)); 43643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 43663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 43673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!contains(nonMirroredEdgeVertices, endpointA) || 43693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !contains(nonMirroredEdgeVertices, endpointB)) 43703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: edge doesn't contain both endpoints, " << endpointA << " and " << endpointB << TestLog::EndMessage 43723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5) 43733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << TestLog::EndMessage; 43743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 43753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 43763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nonMirroredEdgeVertices.erase(endpointA); 43783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nonMirroredEdgeVertices.erase(endpointB); 43793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (nonMirroredEdgeVertices != mirroredEdgeVertices) 43823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 43833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the set of mirrored edges isn't equal to the set of non-mirrored edges (ignoring endpoints and possible middle)" << TestLog::EndMessage 43843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5) 43853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << TestLog::EndMessage; 43863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 43873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 43883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 43963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 43973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 43983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 43993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 44003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 44023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #4 44033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 44043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the vertices on an outer edge don't depend on which of the 44053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * edges it is, other than with respect to component order. 44063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 44073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OuterEdgeVertexSetIndexIndependenceCase : public TestCase 44083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 44103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OuterEdgeVertexSetIndexIndependenceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 44113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 44123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 44133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 44143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_winding (winding) 44153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_usePointMode (usePointMode) 44163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 44173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS); 44183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 44193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 44213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 44223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 44233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 44253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel); 44263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 44283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 44303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 44313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding m_winding; 44323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_usePointMode; 44333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 44353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 44363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> OuterEdgeVertexSetIndexIndependenceCase::generatePatchTessLevels (int numPatches, int constantOuterLevelIndex, float constantOuterLevel) 44383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd(123); 44403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd); 44413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 44423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid OuterEdgeVertexSetIndexIndependenceCase::init (void) 44443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 44453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 44463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 44473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 44493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 44503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 44523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 44533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 44553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 44563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 44573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 44583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 44603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 44613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 44633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 44653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 44673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 44683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 44693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 44703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 44723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 44733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 44743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 44753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 44763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 44783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 44793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) + 44813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 44833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec3 out_te_tessCoord;\n" 44843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 44863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 44873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord;" 44883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n" 44893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(1.0);\n" 44903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 44913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 44923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 44933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 44953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 44973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 44983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 44993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 45003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 45013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 45023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 45043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 45053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 45073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 45083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 45093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 45103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid OuterEdgeVertexSetIndexIndependenceCase::deinit (void) 45123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 45133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 45143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 45153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryOuterEdgeVertexSetIndexIndependenceCase::IterateResult OuterEdgeVertexSetIndexIndependenceCase::iterate (void) 45173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 45183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 45193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 45213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 45223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 45233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 45243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 45253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float singleOuterEdgeLevels[] = { 1.0f, 1.2f, 1.9f, 2.3f, 2.8f, 3.3f, 3.8f, 10.2f, 1.6f, 24.4f, 24.7f, 63.0f }; 45273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<OuterEdgeDescription> edgeDescriptions = outerEdgeDescriptions(m_primitiveType); 45283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 45303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 45313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 6); 45323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once. 45353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxNumVerticesInDrawCall = 0; 45363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(1, 0 /* outer-edge index doesn't affect vertex count */, arrayMax(singleOuterEdgeLevels)); 45383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxNumVerticesInDrawCall = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]); 45393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall); 45433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(singleOuterEdgeLevels); outerEdgeLevelCaseNdx++) 45453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef std::set<Vec3, VecLexLessThan<3> > Vec3Set; 45473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set firstEdgeVertices; 45493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int outerEdgeIndex = 0; outerEdgeIndex < (int)edgeDescriptions.size(); outerEdgeIndex++) 45513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const OuterEdgeDescription& edgeDesc = edgeDescriptions[outerEdgeIndex]; 45533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> patchTessLevels = generatePatchTessLevels(1, outerEdgeIndex, singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 45543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)patchTessLevels.size(), 0, &patchTessLevels[0]) }; 45553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Testing with outer tessellation level " << singleOuterEdgeLevels[outerEdgeLevelCaseNdx] 45573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " for the " << edgeDesc.description() << " edge, and with various levels for other edges" << TestLog::EndMessage; 45583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode), 45613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)patchTessLevels.size()); 45623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int refNumVertices = referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &patchTessLevels[0], &patchTessLevels[2]); 45633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)tfResult.varying.size() != refNumVertices) 45653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the number of vertices returned by transform feedback is " 45673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tfResult.varying.size() << ", expected " << refNumVertices << TestLog::EndMessage 45683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: rendered 1 patch, tessellation levels are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n" 45693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << containerStr(patchTessLevels, 6) << TestLog::EndMessage; 45703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 45723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 45733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Vec3Set currentEdgeVertices; 45773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 45783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Get the vertices on the current outer edge. 45793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for(int vtxNdx = 0; vtxNdx < refNumVertices; vtxNdx++) 45803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& vtx = tfResult.varying[vtxNdx]; 45823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (edgeDesc.contains(vtx)) 45833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Swizzle components to match the order of the first edge. 45853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 45863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentEdgeVertices.insert(outerEdgeIndex == 0 ? vtx 45883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 1 ? vtx.swizzle(1, 0, 2) 45893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 2 ? vtx.swizzle(2, 1, 0) 45903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : Vec3(-1.0f)); 45913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 45923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 45933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 45943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentEdgeVertices.insert(Vec3(outerEdgeIndex == 0 ? vtx.y() 45953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 1 ? vtx.x() 45963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 2 ? vtx.y() 45973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 3 ? vtx.x() 45983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : -1.0f, 45993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.0f, 0.0f)); 46003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 46023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 46033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outerEdgeIndex == 0) 46073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry firstEdgeVertices = currentEdgeVertices; 46083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 46093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compare vertices of this edge to those of the first edge. 46113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentEdgeVertices != firstEdgeVertices) 46133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const swizzleDesc = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? (outerEdgeIndex == 1 ? "(y, x, z)" 46153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 2 ? "(z, y, x)" 46163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) 46173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? (outerEdgeIndex == 1 ? "(x, 0)" 46183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 2 ? "(y, 0)" 46193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : outerEdgeIndex == 3 ? "(x, 0)" 46203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL) 46213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL; 46223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: the set of vertices on the " << edgeDesc.description() << " edge" 46243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " doesn't match the set of vertices on the " << edgeDescriptions[0].description() << " edge" << TestLog::EndMessage 46253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: set of vertices on " << edgeDesc.description() << " edge, components swizzled like " << swizzleDesc 46263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " to match component order on first edge:\n" << containerStr(currentEdgeVertices, 5) 46273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\non " << edgeDescriptions[0].description() << " edge:\n" << containerStr(firstEdgeVertices, 5) << TestLog::EndMessage; 46283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid set of vertices"); 46293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 46303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 46403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 46413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 46423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 46443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #5 46453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 46463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the set of triangles input to the TES only depends on the 46473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * tessellation levels, tessellation mode and spacing mode. Specifically, 46483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * winding doesn't change the set of triangles, though it can change the 46493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * order in which they are input to TES, and can (and will) change the 46503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * vertex order within a triangle. 46513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 46523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvariantTriangleSetCase : public PrimitiveSetInvarianceCase 46533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 46543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 46553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvariantTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing) 46563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY) 46573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS); 46593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 46623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const 46633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog()); 46653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 46673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 46693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #6 46703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 46713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the set of inner triangles input to the TES only depends on 46723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the inner tessellation levels, tessellation mode and spacing mode. 46733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 46743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvariantInnerTriangleSetCase : public PrimitiveSetInvarianceCase 46753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 46763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 46773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvariantInnerTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing) 46783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY) 46793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS); 46813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 46823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 46843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual vector<LevelCase> genTessLevelCases (void) const 46853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSubCases = 4; 46873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<LevelCase> baseResults = PrimitiveSetInvarianceCase::genTessLevelCases(); 46883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<LevelCase> result; 46893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (123); 46903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Generate variants with different values for irrelevant levels. 46923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int baseNdx = 0; baseNdx < (int)baseResults.size(); baseNdx++) 46933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 46943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessLevels& base = baseResults[baseNdx].levels[0]; 46953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessLevels levels = base; 46963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LevelCase levelCase; 46973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 46983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int subNdx = 0; subNdx < numSubCases; subNdx++) 46993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levelCase.levels.push_back(levels); 47013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); i++) 47033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.outer[i] = rnd.getFloat(2.0f, 16.0f); 47043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 47053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.inner[1] = rnd.getFloat(2.0f, 16.0f); 47063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(levelCase); 47093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 47123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct IsInnerTriangleTriangle 47153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Vec3* vertices) const 47173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int v = 0; v < 3; v++) 47193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int c = 0; c < 3; c++) 47203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (vertices[v][c] == 0.0f) 47213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 47253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct IsInnerQuadTriangle 47273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Vec3* vertices) const 47293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int v = 0; v < 3; v++) 47313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int c = 0; c < 2; c++) 47323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (vertices[v][c] == 0.0f || vertices[v][c] == 1.0f) 47333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 47353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 47373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int) const 47393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 47413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), IsInnerTriangleTriangle(), "outer triangles"); 47423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 47433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), IsInnerQuadTriangle(), "outer triangles"); 47443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 47453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 47473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 47483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 47513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 47533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test invariance rule #7 47543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 47553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that the set of outer triangles input to the TES only depends on 47563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * tessellation mode, spacing mode and the inner and outer tessellation 47573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * levels corresponding to the inner and outer edges relevant to that 47583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * triangle. 47593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 47603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvariantOuterTriangleSetCase : public PrimitiveSetInvarianceCase 47613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 47623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 47633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry InvariantOuterTriangleSetCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing) 47643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : PrimitiveSetInvarianceCase(context, name, description, primType, spacing, false, WINDINGUSAGE_VARY) 47653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(primType == TESSPRIMITIVETYPE_TRIANGLES || primType == TESSPRIMITIVETYPE_QUADS); 47673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 47683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 47703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual vector<LevelCase> genTessLevelCases (void) const 47713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSubCasesPerEdge = 4; 47733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numEdges = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 47743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 47753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : -1; 47763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<LevelCase> baseResult = PrimitiveSetInvarianceCase::genTessLevelCases(); 47773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<LevelCase> result; 47783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd (123); 47793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Generate variants with different values for irrelevant levels. 47813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int baseNdx = 0; baseNdx < (int)baseResult.size(); baseNdx++) 47823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessLevels& base = baseResult[baseNdx].levels[0]; 47843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (base.inner[0] == 1.0f || (m_primitiveType == TESSPRIMITIVETYPE_QUADS && base.inner[1] == 1.0f)) 47853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 47863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int edgeNdx = 0; edgeNdx < numEdges; edgeNdx++) 47883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessLevels levels = base; 47903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry LevelCase levelCase; 47913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levelCase.mem = edgeNdx; 47923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int subCaseNdx = 0; subCaseNdx < numSubCasesPerEdge; subCaseNdx++) 47943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levelCase.levels.push_back(levels); 47963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 47973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); i++) 47983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 47993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (i != edgeNdx) 48003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.outer[i] = rnd.getFloat(2.0f, 16.0f); 48013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 48043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry levels.inner[1] = rnd.getFloat(2.0f, 16.0f); 48053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(levelCase); 48083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 48123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry class IsTriangleTriangleOnOuterEdge 48153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 48173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsTriangleTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {} 48183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Vec3* vertices) const 48193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool touchesAppropriateEdge = false; 48213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int v = 0; v < 3; v++) 48223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (vertices[v][m_edgeNdx] == 0.0f) 48233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry touchesAppropriateEdge = true; 48243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (touchesAppropriateEdge) 48263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3 avg = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; 48283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return avg[m_edgeNdx] < avg[(m_edgeNdx+1)%3] && 48293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry avg[m_edgeNdx] < avg[(m_edgeNdx+2)%3]; 48303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 48323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry private: 48353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_edgeNdx; 48363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 48373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry class IsQuadTriangleOnOuterEdge 48393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 48413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsQuadTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {} 48423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool onEdge (const Vec3& v) const 48443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return v[m_edgeNdx%2] == (m_edgeNdx <= 1 ? 0.0f : 1.0f); 48463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static inline bool onAnyEdge (const Vec3& v) 48493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return v[0] == 0.0f || v[0] == 1.0f || v[1] == 0.0f || v[1] == 1.0f; 48513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool operator() (const Vec3* vertices) const 48543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int v = 0; v < 3; v++) 48563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& a = vertices[v]; 48583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& b = vertices[(v+1)%3]; 48593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& c = vertices[(v+2)%3]; 48603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (onEdge(a) && onEdge(b)) 48613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 48623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (onEdge(c) && !onAnyEdge(a) && !onAnyEdge(b) && a[m_edgeNdx%2] == b[m_edgeNdx%2]) 48633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 48643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 48673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry private: 48703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_edgeNdx; 48713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 48723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool compare (const vector<Vec3>& coordsA, const vector<Vec3>& coordsB, int outerEdgeNdx) const 48743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 48763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), 48783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsTriangleTriangleOnOuterEdge(outerEdgeNdx), 48793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("inner triangles, and outer triangles corresponding to other edge than edge " 48803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + outerEdgeDescriptions(m_primitiveType)[outerEdgeNdx].description()).c_str()); 48813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS) 48833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 48843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return compareTriangleSets(coordsA, coordsB, m_testCtx.getLog(), 48853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IsQuadTriangleOnOuterEdge(outerEdgeNdx), 48863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("inner triangles, and outer triangles corresponding to other edge than edge " 48873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + outerEdgeDescriptions(m_primitiveType)[outerEdgeNdx].description()).c_str()); 48883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 48903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 48913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 48933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 48943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 48953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 48963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 48973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Base class for testing individual components of tess coords 48983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 48993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Useful for testing parts of invariance rule #8. 49003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 49013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TessCoordComponentInvarianceCase : public TestCase 49023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 49033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 49043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessCoordComponentInvarianceCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 49053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 49063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 49073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 49083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_winding (winding) 49093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_usePointMode (usePointMode) 49103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 49113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 49123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 49143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 49153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 49163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 49183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string tessEvalOutputComponentStatements (const char* tessCoordComponentName, const char* outputComponentName) const = 0; 49193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool checkTessCoordComponent (float component) const = 0; 49203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 49223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> genTessLevelCases (int numCases); 49233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 16; 49253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 49273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 49283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding m_winding; 49293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_usePointMode; 49303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 49323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 49333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessCoordComponentInvarianceCase::init (void) 49353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 49363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 49373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 49383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 49403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 49413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 49433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 49443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 49463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 49473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 49483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 49493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 49513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 49523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 49543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 49563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 49583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 49593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 49603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 49613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 49633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 49643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 49653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 49663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 49673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 49693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 49703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) + 49723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 49743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec3 out_te_output;\n" 49753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 49773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 49783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tessEvalOutputComponentStatements("gl_TessCoord.x", "out_te_output.x") 49793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tessEvalOutputComponentStatements("gl_TessCoord.y", "out_te_output.y") 49803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 49823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessEvalOutputComponentStatements("gl_TessCoord.z", "out_te_output.z") : 49833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_output.z = 0.0f;\n") + 49843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy, 0.0, 1.0);\n" 49853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(1.0);\n" 49863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 49873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 49893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 49913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 49933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 49943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 49953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 49963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 49973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 49983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 49993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_output") 50003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 50013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 50033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 50043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 50053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 50063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessCoordComponentInvarianceCase::deinit (void) 50083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 50103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 50113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> TessCoordComponentInvarianceCase::genTessLevelCases (int numCases) 50133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random rnd(123); 50153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> result; 50163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numCases; i++) 50183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 6; j++) 50193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(rnd.getFloat(1.0f, 63.0f)); 50203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 50223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 50233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessCoordComponentInvarianceCase::IterateResult TessCoordComponentInvarianceCase::iterate (void) 50253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 50273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 50293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 50303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 50313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 50323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTessLevelCases = 32; 50333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> tessLevels = genTessLevelCases(numTessLevelCases); 50343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 50353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 50373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 50383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 6); 50393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute the number vertices in the largest draw call, so we can allocate the TF buffer just once. 50423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int maxNumVerticesInDrawCall = 0; 50433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numTessLevelCases; i++) 50443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry maxNumVerticesInDrawCall = de::max(maxNumVerticesInDrawCall, referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &tessLevels[6*i+0], &tessLevels[6*i+2])); 50453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler(m_context.getRenderContext(), maxNumVerticesInDrawCall); 50483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < numTessLevelCases; tessLevelCaseNdx++) 50503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Testing with tessellation levels: " << tessellationLevelsString(&tessLevels[6*tessLevelCaseNdx+0], &tessLevels[6*tessLevelCaseNdx+2]) << TestLog::EndMessage; 50523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)6, 0, &tessLevels[6*tessLevelCaseNdx]) }; 50543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode), 50553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], 6); 50563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vtxNdx = 0; vtxNdx < (int)tfResult.varying.size(); vtxNdx++) 50583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Vec3& vec = tfResult.varying[vtxNdx]; 50603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numComps = m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 2; 50613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int compNdx = 0; compNdx < numComps; compNdx++) 50633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!checkTessCoordComponent(vec[compNdx])) 50653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: output value at index " << vtxNdx << " is " 50673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? de::toString(vec) : de::toString(vec.swizzle(0,1))) 50683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 50693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid tessellation coordinate component"); 50703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 50713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 50793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 50803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 50813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 50833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test first part of invariance rule #8 50843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 50853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that all (relevant) components of tess coord are in [0,1]. 50863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 50873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TessCoordComponentRangeCase : public TessCoordComponentInvarianceCase 50883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 50893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 50903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessCoordComponentRangeCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 50913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TessCoordComponentInvarianceCase(context, name, description, primType, spacing, winding, usePointMode) 50923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 50943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 50953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 50963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string tessEvalOutputComponentStatements (const char* tessCoordComponentName, const char* outputComponentName) const 50973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 50983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + "\t" + outputComponentName + " = " + tessCoordComponentName + ";\n"; 50993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool checkTessCoordComponent (float component) const 51023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::inRange(component, 0.0f, 1.0f)) 51043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Failure: tess coord component isn't in range [0,1]" << TestLog::EndMessage; 51063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 51073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 51093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 51133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test second part of invariance rule #8 51143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 51153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Test that all (relevant) components of tess coord are in [0,1] and 51163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 1.0-c is exact for every such component c. 51173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 51183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass OneMinusTessCoordComponentCase : public TessCoordComponentInvarianceCase 51193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 51213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry OneMinusTessCoordComponentCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 51223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TessCoordComponentInvarianceCase(context, name, description, primType, spacing, winding, usePointMode) 51233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 51273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string tessEvalOutputComponentStatements (const char* tessCoordComponentName, const char* outputComponentName) const 51283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return string() + " {\n" 51303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float oneMinusComp = 1.0 - " + tessCoordComponentName + ";\n" 51313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + outputComponentName + " = " + tessCoordComponentName + " + oneMinusComp;\n" 51323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 51333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual bool checkTessCoordComponent (float component) const 51363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (component != 1.0f) 51383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Failure: comp + (1.0-comp) doesn't equal 1.0 for some component of tessellation coordinate" << TestLog::EndMessage; 51403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 51413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 51433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 51473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Test that patch is discarded if relevant outer level <= 0.0 51483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 51493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Draws patches with different combinations of tessellation levels, 51503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * varying which levels are negative. Verifies by checking that colored 51513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * pixels exist inside the area of valid primitives, and only black pixels 51523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * exist inside the area of discarded primitives. An additional sanity 51533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * test is done, checking that the number of primitives written by TF is 51543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * correct. 51553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 51563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PrimitiveDiscardCase : public TestCase 51573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 51593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PrimitiveDiscardCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, SpacingMode spacing, Winding winding, bool usePointMode) 51603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 51613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 51623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_spacing (spacing) 51633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_winding (winding) 51643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_usePointMode (usePointMode) 51653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 51663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 51673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 51693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 51703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 51713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 51733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static vector<float> genAttributes (void); 51743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 51763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 51783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode m_spacing; 51793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding m_winding; 51803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_usePointMode; 51813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 51833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 51843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PrimitiveDiscardCase::init (void) 51863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 51873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 51883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 51893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 51903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 51913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 51923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 51933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 51943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 51953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 51963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 51973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 51983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 51993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 52003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 52023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 52033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 1) out;\n" 52053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_tc_attr[];\n" 52073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp vec2 in_te_positionScale;\n" 52093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp vec2 in_te_positionOffset;\n" 52103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 52123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 52133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_positionScale = vec2(in_tc_attr[6], in_tc_attr[7]);\n" 52143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_positionOffset = vec2(in_tc_attr[8], in_tc_attr[9]);\n" 52153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 52173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 52183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 52203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 52213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 52223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 52233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 52243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 52263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 52273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType, m_spacing, m_winding, m_usePointMode) + 52293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp vec2 in_te_positionScale;\n" 52313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp vec2 in_te_positionOffset;\n" 52323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec3 out_te_tessCoord;\n" 52343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 52363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 52373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_tessCoord = gl_TessCoord;\n" 52383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*in_te_positionScale + in_te_positionOffset, 0.0, 1.0);\n" 52393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 52403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 52423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 52443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 52453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 52463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 52473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = vec4(1.0);\n" 52483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 52493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_tessCoord") 52513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 52523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 52543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 52553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 52563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 52573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PrimitiveDiscardCase::deinit (void) 52593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 52613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 52623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvector<float> PrimitiveDiscardCase::genAttributes (void) 52643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 52653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Generate input attributes (tessellation levels, and position scale and 52663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // offset) for a number of primitives. Each primitive has a different 52673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // combination of tessellatio levels; each level is either a valid 52683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // value or an "invalid" value (negative or zero, chosen from 52693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // invalidTessLevelChoices). 52703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note The attributes are generated in such an order that all of the 52723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // valid attribute tuples come before the first invalid one both 52733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // in the result vector, and when scanning the resulting 2d grid 52743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // of primitives is scanned in y-major order. This makes 52753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verification somewhat simpler. 52763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float baseTessLevels[6] = { 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; 52783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float invalidTessLevelChoices[] = { -0.42f, 0.0f }; 52793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numChoices = 1 + DE_LENGTH_OF_ARRAY(invalidTessLevelChoices); 52803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float choices[6][numChoices]; 52813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<float> result; 52823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int levelNdx = 0; levelNdx < 6; levelNdx++) 52843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int choiceNdx = 0; choiceNdx < numChoices; choiceNdx++) 52853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry choices[levelNdx][choiceNdx] = choiceNdx == 0 ? baseTessLevels[levelNdx] : invalidTessLevelChoices[choiceNdx-1]; 52863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 52873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 52883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numCols = intPow(numChoices, 6/2); // sqrt(numChoices**6) == sqrt(number of primitives) 52893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numRows = numCols; 52903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int index = 0; 52913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int i[6]; 52923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // We could do this with some generic combination-generation function, but meh, it's not that bad. 52933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[2] = 0; i[2] < numChoices; i[2]++) // First outer 52943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[3] = 0; i[3] < numChoices; i[3]++) // Second outer 52953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[4] = 0; i[4] < numChoices; i[4]++) // Third outer 52963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[5] = 0; i[5] < numChoices; i[5]++) // Fourth outer 52973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[0] = 0; i[0] < numChoices; i[0]++) // First inner 52983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (i[1] = 0; i[1] < numChoices; i[1]++) // Second inner 52993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < 6; j++) 53013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back(choices[j][i[j]]); 53023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int col = index % numCols; 53053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int row = index / numCols; 53063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Position scale. 53073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back((float)2.0f / (float)numCols); 53083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back((float)2.0f / (float)numRows); 53093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Position offset. 53103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back((float)col / (float)numCols * 2.0f - 1.0f); 53113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result.push_back((float)row / (float)numRows * 2.0f - 1.0f); 53123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry index++; 53153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 53193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 53203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPrimitiveDiscardCase::IterateResult PrimitiveDiscardCase::iterate (void) 53223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 53233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<Vec3> TFHandler; 53243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 53263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 53273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 53283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 53293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const vector<float> attributes = genAttributes(); 53303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numAttribsPerPrimitive = 6+2+2; // Tess levels, scale, offset. 53313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrimitives = (int)attributes.size() / numAttribsPerPrimitive; 53323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 53333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 53353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 53363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, numAttribsPerPrimitive); 53373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 53393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 53403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check the convenience assertion that all discarded patches come after the last non-discarded patch. 53423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool discardedPatchEncountered = false; 53443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++) 53453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool discard = isPatchDiscarded(m_primitiveType, &attributes[numAttribsPerPrimitive*patchNdx + 2]); 53473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(discard || !discardedPatchEncountered); 53483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry discardedPatchEncountered = discard; 53493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(discardedPatchEncountered); 53513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVerticesInDrawCall = 0; 53553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++) 53563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVerticesInDrawCall += referenceVertexCount(m_primitiveType, m_spacing, m_usePointMode, &attributes[numAttribsPerPrimitive*patchNdx+0], &attributes[numAttribsPerPrimitive*patchNdx+2]); 53573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: rendering " << numPrimitives << " patches; first patches have valid relevant outer levels, " 53593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "but later patches have one or more invalid (i.e. less than or equal to 0.0) relevant outer levels" << TestLog::EndMessage; 53603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler (m_context.getRenderContext(), numVerticesInDrawCall); 53633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, (int)attributes.size(), 0, &attributes[0]) }; 53643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, m_usePointMode), 53653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], (int)attributes.size()); 53663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface pixels = getPixels(renderCtx, viewport); 53673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Image("RenderedImage", "Rendered image", pixels); 53693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)tfResult.varying.size() != numVerticesInDrawCall) 53713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected " << numVerticesInDrawCall << " vertices from transform feedback, got " << tfResult.varying.size() << TestLog::EndMessage; 53733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Wrong number of tessellation coordinates"); 53743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 53753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 53763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that white pixels are found around every non-discarded 53783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // patch, and that only black pixels are found after the last 53793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // non-discarded patch. 53803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int lastWhitePixelRow = 0; 53823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int secondToLastWhitePixelRow = 0; 53833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int lastWhitePixelColumnOnSecondToLastWhitePixelRow = 0; 53843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int patchNdx = 0; patchNdx < numPrimitives; patchNdx++) 53863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const attr = &attributes[numAttribsPerPrimitive*patchNdx]; 53883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool validLevels = !isPatchDiscarded(m_primitiveType, &attr[2]); 53893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (validLevels) 53913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 53923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Not a discarded patch; check that at least one white pixel is found in its area. 53933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 53943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const scale = &attr[6]; 53953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float* const offset = &attr[8]; 53963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int x0 = (int)(( offset[0] + 1.0f)*0.5f*(float)pixels.getWidth()) - 1; 53973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int x1 = (int)((scale[0] + offset[0] + 1.0f)*0.5f*(float)pixels.getWidth()) + 1; 53983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int y0 = (int)(( offset[1] + 1.0f)*0.5f*(float)pixels.getHeight()) - 1; 53993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int y1 = (int)((scale[1] + offset[1] + 1.0f)*0.5f*(float)pixels.getHeight()) + 1; 54003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isMSAA = renderCtx.getRenderTarget().getNumSamples() > 1; 54013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool pixelOk = false; 54023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (y1 > lastWhitePixelRow) 54043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry secondToLastWhitePixelRow = lastWhitePixelRow; 54063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry lastWhitePixelRow = y1; 54073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry lastWhitePixelColumnOnSecondToLastWhitePixelRow = x1; 54093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = y0; y <= y1 && !pixelOk; y++) 54113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = x0; x <= x1 && !pixelOk; x++) 54123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!de::inBounds(x, 0, pixels.getWidth()) || !de::inBounds(y, 0, pixels.getHeight())) 54143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 54153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isMSAA) 54173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pixels.getPixel(x, y) != tcu::RGBA::black) 54193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pixelOk = true; 54203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 54223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pixels.getPixel(x, y) == tcu::RGBA::white) 54243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pixelOk = true; 54253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!pixelOk) 54293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected at least one " << (isMSAA ? "non-black" : "white") << " pixel in the rectangle " 54313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "[x0=" << x0 << ", y0=" << y0 << ", x1=" << x1 << ", y1=" << y1 << "]" << TestLog::EndMessage 54323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: the rectangle approximately corresponds to the patch with these tessellation levels: " 54333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tessellationLevelsString(&attr[0], &attr[1]) << TestLog::EndMessage; 54343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 54353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 54363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 54393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // First discarded primitive patch; the remaining are guaranteed to be discarded ones as well. 54413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < pixels.getHeight(); y++) 54433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < pixels.getWidth(); x++) 54443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (y > lastWhitePixelRow || (y > secondToLastWhitePixelRow && x > lastWhitePixelColumnOnSecondToLastWhitePixelRow)) 54463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pixels.getPixel(x, y) != tcu::RGBA::black) 54483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: expected all pixels to be black in the area " 54503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << (lastWhitePixelColumnOnSecondToLastWhitePixelRow < pixels.getWidth()-1 54513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ? string() + "y > " + de::toString(lastWhitePixelRow) + " || (y > " + de::toString(secondToLastWhitePixelRow) 54523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + " && x > " + de::toString(lastWhitePixelColumnOnSecondToLastWhitePixelRow) + ")" 54533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : string() + "y > " + de::toString(lastWhitePixelRow)) 54543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " (they all correspond to patches that should be discarded)" << TestLog::EndMessage 54553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << "Note: pixel " << tcu::IVec2(x, y) << " isn't black" << TestLog::EndMessage; 54563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 54573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 54583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 54633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 54683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 54703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 54713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 54723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 54733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 54743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Case testing user-defined IO between TCS and TES 54753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 54763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * TCS outputs various values to TES, including aggregates. The outputs 54773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * can be per-patch or per-vertex, and if per-vertex, they can also be in 54783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * an IO block. Per-vertex input array size can be left implicit (i.e. 54793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * inputArray[]) or explicit either by gl_MaxPatchVertices or an integer 54803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * literal whose value is queried from GL. 54813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 54823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * The values output are generated in TCS and verified in TES against 54833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * similarly generated values. In case a verification of a value fails, the 54843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * index of the invalid value is output with TF. 54853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * As a sanity check, also the rendering result is verified (against pre- 54863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * rendered reference). 54873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 54883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass UserDefinedIOCase : public TestCase 54893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 54903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 54913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum IOType 54923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 54933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IO_TYPE_PER_PATCH = 0, 54943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IO_TYPE_PER_PATCH_ARRAY, 54958cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry IO_TYPE_PER_PATCH_BLOCK, 54968cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry IO_TYPE_PER_PATCH_BLOCK_ARRAY, 54973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IO_TYPE_PER_VERTEX, 54983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IO_TYPE_PER_VERTEX_BLOCK, 54993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IO_TYPE_LAST 55013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 55023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum VertexIOArraySize 55043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VERTEX_IO_ARRAY_SIZE_IMPLICIT = 0, 55063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN, //!< Use gl_MaxPatchVertices as size for per-vertex input array. 55073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY, //!< Query GL_MAX_PATCH_VERTICES, and use that as size for per-vertex input array. 55083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry VERTEX_IO_ARRAY_SIZE_LAST 55103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 55113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry UserDefinedIOCase (Context& context, const char* name, const char* description, TessPrimitiveType primType, IOType ioType, VertexIOArraySize vertexIOArraySize, const char* referenceImagePath) 55133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 55143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_primitiveType (primType) 55153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_ioType (ioType) 55163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_vertexIOArraySize (vertexIOArraySize) 55173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePath (referenceImagePath) 55183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 55203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 55223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 55233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 55243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 55263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef string (*BasicTypeVisitFunc)(const string& name, glu::DataType type, int indentationDepth); //!< See glslTraverseBasicTypes below. 55273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry class TopLevelObject 55293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 55313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual ~TopLevelObject (void) {} 55323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string name (void) const = 0; 55348cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry virtual string declare (void) const = 0; 55358cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry virtual string declareArray (const string& arraySizeExpr) const = 0; 55368cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry virtual string glslTraverseBasicTypeArray (int numArrayElements, //!< If negative, traverse just array[gl_InvocationID], not all indices. 55373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int indentationDepth, 55383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicTypeVisitFunc) const = 0; 55398cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry virtual string glslTraverseBasicType (int indentationDepth, 55408cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry BasicTypeVisitFunc) const = 0; 55413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual int numBasicSubobjectsInElementType (void) const = 0; 55423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry virtual string basicSubobjectAtIndex (int index, int arraySize) const = 0; 55433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 55443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry class Variable : public TopLevelObject 55463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 55483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Variable (const string& name_, const glu::VarType& type, bool isArray) 55493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_name (name_) 55503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_type (type) 55513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isArray (isArray) 55523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!type.isArrayType()); 55543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 55553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string name (void) const { return m_name; } 55578cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string declare (void) const; 55588cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string declareArray (const string& arraySizeExpr) const; 55598cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string glslTraverseBasicTypeArray (int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const; 55608cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc) const; 55613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBasicSubobjectsInElementType (void) const; 55623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string basicSubobjectAtIndex (int index, int arraySize) const; 55633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry private: 55653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string m_name; 55663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::VarType m_type; //!< If this Variable is an array element, m_type is the element type; otherwise just the variable type. 55673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool m_isArray; 55683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 55693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry class IOBlock : public TopLevelObject 55713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry public: 55733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry struct Member 55743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string name; 55763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::VarType type; 55773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Member (const string& n, const glu::VarType& t) : name(n), type(t) {} 55783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 55793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IOBlock (const string& blockName, const string& interfaceName, const vector<Member>& members) 55813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_blockName (blockName) 55823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_interfaceName (interfaceName) 55833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_members (members) 55843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 55853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 55863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string name (void) const { return m_interfaceName; } 55888cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string declare (void) const; 55898cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string declareArray (const string& arraySizeExpr) const; 55908cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string glslTraverseBasicTypeArray (int numArrayElements, int indentationDepth, BasicTypeVisitFunc) const; 55918cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc) const; 55923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numBasicSubobjectsInElementType (void) const; 55933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string basicSubobjectAtIndex (int index, int arraySize) const; 55943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 55953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry private: 55963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string m_blockName; 55973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string m_interfaceName; 55983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Member> m_members; 55993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 56003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static string glslTraverseBasicTypes (const string& rootName, 56023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType& rootType, 56033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int arrayNestingDepth, 56043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int indentationDepth, 56053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicTypeVisitFunc visit); 56063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static string glslAssignBasicTypeObject (const string& name, glu::DataType, int indentationDepth); 56083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static string glslCheckBasicTypeObject (const string& name, glu::DataType, int indentationDepth); 56093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static int numBasicSubobjectsInElementType (const vector<SharedPtr<TopLevelObject> >&); 56103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static string basicSubobjectAtIndex (int index, const vector<SharedPtr<TopLevelObject> >&, int topLevelArraySizes); 56113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56128cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry enum 56138cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 56148cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry RENDER_SIZE = 256 56158cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry }; 56168cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry enum 56178cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 56188cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry NUM_OUTPUT_VERTICES = 5 56198cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry }; 56208cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry enum 56218cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 56228cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry NUM_PER_PATCH_ARRAY_ELEMS = 3 56238cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry }; 56248cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry enum 56258cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 56268cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry NUM_PER_PATCH_BLOCKS = 2 56278cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry }; 56283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType m_primitiveType; 56303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const IOType m_ioType; 56313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const VertexIOArraySize m_vertexIOArraySize; 56323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePath; 56333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<glu::StructType> m_structTypes; 56353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<SharedPtr<TopLevelObject> > m_tcsOutputs; 56363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<SharedPtr<TopLevelObject> > m_tesInputs; 56373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 56393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 56403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 56423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Generate GLSL code to traverse (possibly aggregate) object 56433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 56443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Generates a string that represents GLSL code that traverses the 56453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * basic-type subobjects in a rootType-typed object named rootName. Arrays 56463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * are traversed with loops and struct members are each traversed 56473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * separately. The code for each basic-type subobject is generated with 56483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * the function given as the 'visit' argument. 56493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 56503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::glslTraverseBasicTypes (const string& rootName, 56513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType& rootType, 56523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int arrayNestingDepth, 56533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int indentationDepth, 56543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry BasicTypeVisitFunc visit) 56553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 56563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (rootType.isBasicType()) 56573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return visit(rootName, rootType.getBasicType(), indentationDepth); 56583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (rootType.isArrayType()) 56593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 56603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string indentation = string(indentationDepth, '\t'); 56613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string loopIndexName = "i" + de::toString(arrayNestingDepth); 56623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string arrayLength = de::toString(rootType.getArraySize()); 56633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return indentation + "for (int " + loopIndexName + " = 0; " + loopIndexName + " < " + de::toString(rootType.getArraySize()) + "; " + loopIndexName + "++)\n" + 56643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "{\n" + 56653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glslTraverseBasicTypes(rootName + "[" + loopIndexName + "]", rootType.getElementType(), arrayNestingDepth+1, indentationDepth+1, visit) + 56663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "}\n"; 56673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 56683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (rootType.isStructType()) 56693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 56703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::StructType& structType = *rootType.getStructPtr(); 56713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numMembers = structType.getNumMembers(); 56723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 56733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int membNdx = 0; membNdx < numMembers; membNdx++) 56753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 56763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::StructMember& member = structType.getMember(membNdx); 56773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += glslTraverseBasicTypes(rootName + "." + member.getName(), member.getType(), arrayNestingDepth, indentationDepth, visit); 56783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 56793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 56813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 56823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 56833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 56843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 56853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 56863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 56873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 56883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 56898cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::Variable::declare (void) const 56908cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry{ 56918cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(!m_isArray); 56928cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return de::toString(glu::declare(m_type, m_name)) + ";\n"; 56938cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry} 56948cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 56958cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::Variable::declareArray (const string& sizeExpr) const 56963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 56978cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(m_isArray); 56988cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return de::toString(glu::declare(m_type, m_name)) + "[" + sizeExpr + "];\n"; 56993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57018cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::IOBlock::declare (void) const 57023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57038cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry std::ostringstream buf; 57048cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57058cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << m_blockName << "\n" 57068cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry << "{\n"; 57078cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)m_members.size(); i++) 57098cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << "\t" << glu::declare(m_members[i].type, m_members[i].name) << ";\n"; 57108cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57118cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << "} " << m_interfaceName << ";\n"; 57128cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return buf.str(); 57138cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry} 57148cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57158cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::IOBlock::declareArray (const string& sizeExpr) const 57168cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry{ 57178cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry std::ostringstream buf; 57188cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57198cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << m_blockName << "\n" 57208cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry << "{\n"; 57218cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57228cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry for (int i = 0; i < (int)m_members.size(); i++) 57238cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << "\t" << glu::declare(m_members[i].type, m_members[i].name) << ";\n"; 57248cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57258cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry buf << "} " << m_interfaceName << "[" << sizeExpr << "];\n"; 57268cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return buf.str(); 57273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57298cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::Variable::glslTraverseBasicTypeArray (int numArrayElements, int indentationDepth, BasicTypeVisitFunc visit) const 57303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57318cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(m_isArray); 57328cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57338cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool traverseAsArray = numArrayElements >= 0; 57348cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const string traversedName = m_name + (!traverseAsArray ? "[gl_InvocationID]" : ""); 57353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType type = traverseAsArray ? glu::VarType(m_type, numArrayElements) : m_type; 57363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return UserDefinedIOCase::glslTraverseBasicTypes(traversedName, type, 0, indentationDepth, visit); 57383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57408cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::Variable::glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc visit) const 57418cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry{ 57428cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(!m_isArray); 57438cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57448cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return UserDefinedIOCase::glslTraverseBasicTypes(m_name, m_type, 0, indentationDepth, visit); 57458cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry} 57468cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57478cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::IOBlock::glslTraverseBasicTypeArray (int numArrayElements, int indentationDepth, BasicTypeVisitFunc visit) const 57483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numArrayElements >= 0) 57503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 57513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string indentation = string(indentationDepth, '\t'); 57523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result = indentation + "for (int i0 = 0; i0 < " + de::toString(numArrayElements) + "; i0++)\n" + 57533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "{\n"; 57543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)m_members.size(); i++) 57553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "[i0]." + m_members[i].name, m_members[i].type, 1, indentationDepth+1, visit); 57563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += indentation + "}\n"; 57573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 57583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 57593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 57603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 57613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 57623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)m_members.size(); i++) 57633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "[gl_InvocationID]." + m_members[i].name, m_members[i].type, 0, indentationDepth, visit); 57643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 57653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 57663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57688cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57698cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyrystring UserDefinedIOCase::IOBlock::glslTraverseBasicType (int indentationDepth, BasicTypeVisitFunc visit) const 57708cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry{ 57718cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry string result; 57728cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry for (int i = 0; i < (int)m_members.size(); i++) 57738cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result += UserDefinedIOCase::glslTraverseBasicTypes(m_interfaceName + "." + m_members[i].name, m_members[i].type, 0, indentationDepth, visit); 57748cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry return result; 57758cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry} 57768cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 57773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint UserDefinedIOCase::Variable::numBasicSubobjectsInElementType (void) const 57783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return numBasicSubobjects(m_type); 57803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint UserDefinedIOCase::IOBlock::numBasicSubobjectsInElementType (void) const 57833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = 0; 57853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)m_members.size(); i++) 57863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += numBasicSubobjects(m_members[i].type); 57873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 57883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 57893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::Variable::basicSubobjectAtIndex (int subobjectIndex, int arraySize) const 57913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 57923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType type = m_isArray ? glu::VarType(m_type, arraySize) : m_type; 57933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int currentIndex = 0; 57943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 57953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (glu::BasicTypeIterator basicIt = glu::BasicTypeIterator::begin(&type); 57963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry basicIt != glu::BasicTypeIterator::end(&type); 57973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++basicIt) 57983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 57993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentIndex == subobjectIndex) 58003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_name + de::toString(glu::TypeAccessFormat(type, basicIt.getPath())); 58013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentIndex++; 58023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 58033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 58043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 58053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::IOBlock::basicSubobjectAtIndex (int subobjectIndex, int arraySize) const 58083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int currentIndex = 0; 58103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int arrayNdx = 0; arrayNdx < arraySize; arrayNdx++) 58113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 58123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int memberNdx = 0; memberNdx < (int)m_members.size(); memberNdx++) 58133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 58143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType& membType = m_members[memberNdx].type; 58153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (glu::BasicTypeIterator basicIt = glu::BasicTypeIterator::begin(&membType); 58163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry basicIt != glu::BasicTypeIterator::end(&membType); 58173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++basicIt) 58183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 58193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentIndex == subobjectIndex) 58203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_interfaceName + "[" + de::toString(arrayNdx) + "]." + m_members[memberNdx].name + de::toString(glu::TypeAccessFormat(membType, basicIt.getPath())); 58213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentIndex++; 58223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 58233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 58243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 58253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 58263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 58273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Used as the 'visit' argument for glslTraverseBasicTypes. 58303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::glslAssignBasicTypeObject (const string& name, glu::DataType type, int indentationDepth) 58313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(type); 58333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string indentation = string(indentationDepth, '\t'); 58343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 58353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += indentation + name + " = "; 58373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type != glu::TYPE_FLOAT) 58393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += string() + glu::getDataTypeName(type) + "("; 58403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < scalarSize; i++) 58413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += (i > 0 ? ", v+" + de::floatToString(0.8f*(float)i, 1) 58423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : "v"); 58433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type != glu::TYPE_FLOAT) 58443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += ")"; 58453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += ";\n" + 58463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "v += 0.4;\n"; 58473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 58483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Used as the 'visit' argument for glslTraverseBasicTypes. 58513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::glslCheckBasicTypeObject (const string& name, glu::DataType type, int indentationDepth) 58523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int scalarSize = glu::getDataTypeScalarSize(type); 58543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string indentation = string(indentationDepth, '\t'); 58553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string result; 58563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += indentation + "allOk = allOk && compare_" + glu::getDataTypeName(type) + "(" + name + ", "; 58583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type != glu::TYPE_FLOAT) 58603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += string() + glu::getDataTypeName(type) + "("; 58613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < scalarSize; i++) 58623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += (i > 0 ? ", v+" + de::floatToString(0.8f*(float)i, 1) 58633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : "v"); 58643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (type != glu::TYPE_FLOAT) 58653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += ")"; 58663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += ");\n" + 58673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "v += 0.4;\n" + 58683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry indentation + "if (allOk) firstFailedInputIndex++;\n"; 58693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 58713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint UserDefinedIOCase::numBasicSubobjectsInElementType (const vector<SharedPtr<TopLevelObject> >& objects) 58743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int result = 0; 58763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < (int)objects.size(); i++) 58773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry result += objects[i]->numBasicSubobjectsInElementType(); 58783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return result; 58793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystring UserDefinedIOCase::basicSubobjectAtIndex (int subobjectIndex, const vector<SharedPtr<TopLevelObject> >& objects, int topLevelArraySize) 58823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int currentIndex = 0; 58843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int objectIndex = 0; 58853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (; currentIndex < subobjectIndex; objectIndex++) 58863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentIndex += objects[objectIndex]->numBasicSubobjectsInElementType() * topLevelArraySize; 58873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (currentIndex > subobjectIndex) 58883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 58893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry objectIndex--; 58903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry currentIndex -= objects[objectIndex]->numBasicSubobjectsInElementType() * topLevelArraySize; 58913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 58923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return objects[objectIndex]->basicSubobjectAtIndex(subobjectIndex - currentIndex, topLevelArraySize); 58943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 58953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 58963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UserDefinedIOCase::init (void) 58973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 58983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 58993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 59003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59018cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool isPerPatchIO = m_ioType == IO_TYPE_PER_PATCH || 59028cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry m_ioType == IO_TYPE_PER_PATCH_ARRAY || 59038cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry m_ioType == IO_TYPE_PER_PATCH_BLOCK || 59048cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY; 59058cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 59063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool isExplicitVertexArraySize = m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN || 59073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY; 59083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string vertexAttrArrayInputSize = m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_IMPLICIT ? "" 59103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN ? "gl_MaxPatchVertices" 59113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_vertexIOArraySize == VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY ? de::toString(m_context.getContextInfo().getInt(GL_MAX_PATCH_VERTICES)) 59123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL; 59133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const maybePatch = isPerPatchIO ? "patch " : ""; 59153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string outMaybePatch = string() + maybePatch + "out "; 59163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string inMaybePatch = string() + maybePatch + "in "; 59178cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool useBlock = m_ioType == IO_TYPE_PER_VERTEX_BLOCK || 59188cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry m_ioType == IO_TYPE_PER_PATCH_BLOCK || 59198cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY; 59203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string tcsDeclarations; 59223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string tcsStatements; 59233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string tesDeclarations; 59253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry string tesStatements; 59263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 59283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_structTypes.push_back(glu::StructType("S")); 59293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType highpFloat (glu::TYPE_FLOAT, glu::PRECISION_HIGHP); 59313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::StructType& structType = m_structTypes.back(); 59323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VarType structVarType (&structType); 593302238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry bool usedStruct = false; 59343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry structType.addMember("x", glu::VarType(glu::TYPE_INT, glu::PRECISION_HIGHP)); 59363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry structType.addMember("y", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)); 593702238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 593802238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry if (useBlock) 593902238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry { 594002238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry // It is illegal to have a structure containing an array as an output variable 594102238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry structType.addMember("z", glu::VarType(highpFloat, 2)); 594202238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry } 59433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (useBlock) 59453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 59468cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool useLightweightBlock = (m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY); // use leaner block to make sure it is not larger than allowed (per-patch storage is very limited) 59478cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry vector<IOBlock::Member> blockMembers; 59488cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 59498cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (!useLightweightBlock) 59508cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry blockMembers.push_back(IOBlock::Member("blockS", structVarType)); 59518cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 59523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockMembers.push_back(IOBlock::Member("blockFa", glu::VarType(highpFloat, 3))); 59533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockMembers.push_back(IOBlock::Member("blockSa", glu::VarType(structVarType, 2))); 59543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry blockMembers.push_back(IOBlock::Member("blockF", highpFloat)); 59553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tcsOutputs.push_back (SharedPtr<TopLevelObject>(new IOBlock("TheBlock", "tcBlock", blockMembers))); 59573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tesInputs.push_back (SharedPtr<TopLevelObject>(new IOBlock("TheBlock", "teBlock", blockMembers))); 595802238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 595902238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry usedStruct = true; 59603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 59613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 59623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 59633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable var0("in_te_s", structVarType, m_ioType != IO_TYPE_PER_PATCH); 59643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Variable var1("in_te_f", highpFloat, m_ioType != IO_TYPE_PER_PATCH); 59653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 596602238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry if (m_ioType != IO_TYPE_PER_PATCH_ARRAY) 596702238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry { 596802238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry // Arrays of structures are disallowed, add struct cases only if not arrayed variable 596902238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry m_tcsOutputs.push_back (SharedPtr<TopLevelObject>(new Variable(var0))); 597002238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry m_tesInputs.push_back (SharedPtr<TopLevelObject>(new Variable(var0))); 597102238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 597202238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry usedStruct = true; 597302238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry } 597402238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 59753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tcsOutputs.push_back (SharedPtr<TopLevelObject>(new Variable(var1))); 59763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_tesInputs.push_back (SharedPtr<TopLevelObject>(new Variable(var1))); 59773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 59783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59798cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcsDeclarations += "in " + Variable("in_tc_attr", highpFloat, true).declareArray(vertexAttrArrayInputSize); 598002238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 598102238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry if (usedStruct) 598202238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry tcsDeclarations += de::toString(glu::declare(structType)) + ";\n"; 598302238eb8729ed058f65776b86a8b08fba11ab9cdJarkko Pöyry 59843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcsStatements += "\t{\n" 59853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\t\thighp float v = 1.3;\n"; 59863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 59873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tcsOutputNdx = 0; tcsOutputNdx < (int)m_tcsOutputs.size(); tcsOutputNdx++) 59883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 59898cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const TopLevelObject& output = *m_tcsOutputs[tcsOutputNdx]; 59908cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const int numElements = !isPerPatchIO ? -1 //!< \note -1 means indexing with gl_InstanceID 59918cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH ? 1 59928cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_ARRAY ? NUM_PER_PATCH_ARRAY_ELEMS 59938cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK ? 1 59948cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY ? NUM_PER_PATCH_BLOCKS 59958cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : -2; 59968cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool isArray = (numElements != 1); 59978cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 59988cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(numElements != -2); 59998cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 60008cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (isArray) 6001aabcb3260e4d63ae9fff43a9d693d9273fd5993bJarkko Pöyry { 6002aabcb3260e4d63ae9fff43a9d693d9273fd5993bJarkko Pöyry // \note: TCS output arrays are always implicitly-sized 6003eeec8accefdba51359d238575ade720d02a90276Pyry Haulos tcsDeclarations += outMaybePatch + output.declareArray(m_ioType == IO_TYPE_PER_PATCH_ARRAY ? de::toString(int(NUM_PER_PATCH_ARRAY_ELEMS)) 6004eeec8accefdba51359d238575ade720d02a90276Pyry Haulos : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY ? de::toString(int(NUM_PER_PATCH_BLOCKS)) 60058cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : ""); 6006aabcb3260e4d63ae9fff43a9d693d9273fd5993bJarkko Pöyry } 60078cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry else 60088cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcsDeclarations += outMaybePatch + output.declare(); 60093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isPerPatchIO) 60113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcsStatements += "\t\tv += float(gl_InvocationID)*" + de::floatToString(0.4f*output.numBasicSubobjectsInElementType(), 1) + ";\n"; 60123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60138cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcsStatements += "\n\t\t// Assign values to output " + output.name() + "\n"; 60148cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (isArray) 60158cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcsStatements += output.glslTraverseBasicTypeArray(numElements, 2, glslAssignBasicTypeObject); 60168cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry else 60178cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcsStatements += output.glslTraverseBasicType(2, glslAssignBasicTypeObject); 60183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isPerPatchIO) 6020eeec8accefdba51359d238575ade720d02a90276Pyry Haulos tcsStatements += "\t\tv += float(" + de::toString(int(NUM_OUTPUT_VERTICES)) + "-gl_InvocationID-1)*" + de::floatToString(0.4f*output.numBasicSubobjectsInElementType(), 1) + ";\n"; 60213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 60223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcsStatements += "\t}\n"; 60233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60248cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (usedStruct) 60258cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tesDeclarations += de::toString(glu::declare(structType)) + ";\n"; 60268cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 60273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tesStatements += "\tbool allOk = true;\n" 6028ade588f3b2b1b6d007b9681e95434dc4a4bd46caJarkko Pöyry "\thighp uint firstFailedInputIndex = 0u;\n" 60293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\t{\n" 60303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\t\thighp float v = 1.3;\n"; 60313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tesInputNdx = 0; tesInputNdx < (int)m_tesInputs.size(); tesInputNdx++) 60323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 60338cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const TopLevelObject& input = *m_tesInputs[tesInputNdx]; 60348cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const int numElements = !isPerPatchIO ? (int)NUM_OUTPUT_VERTICES 60358cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH ? 1 60368cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK ? 1 60378cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_ARRAY ? NUM_PER_PATCH_ARRAY_ELEMS 60388cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY ? NUM_PER_PATCH_BLOCKS 60398cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : -2; 60408cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const bool isArray = (numElements != 1); 60418cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 60428cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry DE_ASSERT(numElements != -2); 60438cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 60448cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (isArray) 6045eeec8accefdba51359d238575ade720d02a90276Pyry Haulos tesDeclarations += inMaybePatch + input.declareArray(m_ioType == IO_TYPE_PER_PATCH_ARRAY ? de::toString(int(NUM_PER_PATCH_ARRAY_ELEMS)) 6046eeec8accefdba51359d238575ade720d02a90276Pyry Haulos : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY ? de::toString(int(NUM_PER_PATCH_BLOCKS)) 60478cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : isExplicitVertexArraySize ? de::toString(vertexAttrArrayInputSize) 60488cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : ""); 60498cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry else 60508cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tesDeclarations += inMaybePatch + input.declare(); 60518cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 60528cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tesStatements += "\n\t\t// Check values in input " + input.name() + "\n"; 60538cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry if (isArray) 60548cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tesStatements += input.glslTraverseBasicTypeArray(numElements, 2, glslCheckBasicTypeObject); 60558cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry else 60568cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tesStatements += input.glslTraverseBasicType(2, glslCheckBasicTypeObject); 60573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 60583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tesStatements += "\t}\n"; 60593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 60603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 60623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 60633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp float in_v_attr;\n" 60653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp float in_tc_attr;\n" 60663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 60683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 60693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_tc_attr = in_v_attr;\n" 60703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 60713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 60733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 60743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6075eeec8accefdba51359d238575ade720d02a90276Pyry Haulos "layout (vertices = " + de::toString(int(NUM_OUTPUT_VERTICES)) + ") out;\n" 60763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tcsDeclarations + 60783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp vec2 in_te_positionScale;\n" 60803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch out highp vec2 in_te_positionOffset;\n" 60813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 60833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 60843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tcsStatements + 60853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_positionScale = vec2(in_tc_attr[6], in_tc_attr[7]);\n" 60873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_te_positionOffset = vec2(in_tc_attr[8], in_tc_attr[9]);\n" 60883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = in_tc_attr[0];\n" 60903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = in_tc_attr[1];\n" 60913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 60923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 60933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 60943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 60953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 60963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 60973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 60983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 60993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 61003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(m_primitiveType) + 61023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tesDeclarations + 61043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp vec2 in_te_positionScale;\n" 61063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "patch in highp vec2 in_te_positionOffset;\n" 61073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 61093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "// Will contain the index of the first incorrect input,\n" 61103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "// or the number of inputs if all are correct\n" 61113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "flat out highp uint out_te_firstFailedInputIndex;\n" 61123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "bool compare_int (int a, int b) { return a == b; }\n" 61143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "bool compare_float (float a, float b) { return abs(a - b) < 0.01f; }\n" 61153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "bool compare_vec4 (vec4 a, vec4 b) { return all(lessThan(abs(a - b), vec4(0.01f))); }\n" 61163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 61183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 61193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + tesStatements + 61203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.xy*in_te_positionScale + in_te_positionOffset, 0.0, 1.0);\n" 61223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = allOk ? vec4(0.0, 1.0, 0.0, 1.0)\n" 61233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " : vec4(1.0, 0.0, 0.0, 1.0);\n" 61243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " out_te_firstFailedInputIndex = firstFailedInputIndex;\n" 61253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 61263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 61283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 61303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 61323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 61333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 61343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 61353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 61363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 61373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying ("out_te_firstFailedInputIndex") 61393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode (GL_INTERLEAVED_ATTRIBS))); 61403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 61423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 61433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 61443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 61453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid UserDefinedIOCase::deinit (void) 61473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 61483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 61493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 61503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61513c827367444ee418f129b2c238299f49d3264554Jarkko PoyryUserDefinedIOCase::IterateResult UserDefinedIOCase::iterate (void) 61523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 61533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef TransformFeedbackHandler<deUint32> TFHandler; 61543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 61563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 61573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 61583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 61593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float attributes[6+2+2] = { /* inner */ 3.0f, 4.0f, /* outer */ 5.0f, 6.0f, 7.0f, 8.0f, /* pos. scale */ 1.2f, 1.3f, /* pos. offset */ -0.3f, -0.4f }; 61603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 61613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVertices = referenceVertexCount(m_primitiveType, SPACINGMODE_EQUAL, false, &attributes[0], &attributes[2]); 61623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler tfHandler (renderCtx, numVertices); 61638cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry tcu::ResultCollector result; 61643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 61663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 61673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, DE_LENGTH_OF_ARRAY(attributes)); 61683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 61703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 61713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 61733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 1, DE_LENGTH_OF_ARRAY(attributes), 0, &attributes[0]) }; 61743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TFHandler::Result tfResult = tfHandler.renderAndGetPrimitives(programGL, outputPrimitiveTypeGL(m_primitiveType, false), 61753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_LENGTH_OF_ARRAY(bindings), &bindings[0], DE_LENGTH_OF_ARRAY(attributes)); 61763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 61783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface pixels = getPixels(renderCtx, viewport); 61793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePath.c_str()); 61803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), pixels.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT); 61813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 61838cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result.fail("Image comparison failed"); 61843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 61853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 61863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)tfResult.varying.size() != numVertices) 61873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 61883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: transform feedback returned " << tfResult.varying.size() << " vertices; expected " << numVertices << TestLog::EndMessage; 61898cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result.fail("Wrong number of vertices"); 61903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 61918cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry else 61923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 61938cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const int topLevelArraySize = (m_ioType == IO_TYPE_PER_PATCH ? 1 61948cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_ARRAY ? NUM_PER_PATCH_ARRAY_ELEMS 61958cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK ? 1 61968cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : m_ioType == IO_TYPE_PER_PATCH_BLOCK_ARRAY ? NUM_PER_PATCH_BLOCKS 61978cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry : (int)NUM_OUTPUT_VERTICES); 61983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numTEInputs = numBasicSubobjectsInElementType(m_tesInputs) * topLevelArraySize; 61993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vertexNdx = 0; vertexNdx < (int)numVertices; vertexNdx++) 62013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tfResult.varying[vertexNdx] > (deUint32)numTEInputs) 62033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: out_te_firstFailedInputIndex has value " << tfResult.varying[vertexNdx] 62053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", should be in range [0, " << numTEInputs << "]" << TestLog::EndMessage; 62068cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result.fail("Invalid transform feedback output"); 62073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (tfResult.varying[vertexNdx] != (deUint32)numTEInputs) 62093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Failure: in tessellation evaluation shader, check for input " 62113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << basicSubobjectAtIndex(tfResult.varying[vertexNdx], m_tesInputs, topLevelArraySize) << " failed" << TestLog::EndMessage; 62128cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result.fail("Invalid input value in tessellation evaluation shader"); 62133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62188cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry result.setTestContextResult(m_testCtx); 62193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 62203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 62213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*! 62233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Pass gl_Position between VS and TCS, or between TCS and TES. 62243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 62253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * In TCS gl_Position is in the gl_out[] block and in TES in the gl_in[] 62263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * block, and has no special semantics in those. Arbitrary vec4 data can 62273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * thus be passed there. 62283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 62293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GLPositionCase : public TestCase 62303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 62313c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 62323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseType 62333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_VS_TO_TCS = 0, 62353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_TCS_TO_TES, 62363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_VS_TO_TCS_TO_TES, 62373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASETYPE_LAST 62393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 62403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLPositionCase (Context& context, const char* name, const char* description, CaseType caseType, const char* referenceImagePath) 62423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 62433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_caseType (caseType) 62443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_referenceImagePath (referenceImagePath) 62453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 62493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 62503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 62513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getCaseTypeName (CaseType type); 62533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 62553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int RENDER_SIZE = 256; 62563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseType m_caseType; 62583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string m_referenceImagePath; 62593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry SharedPtr<const glu::ShaderProgram> m_program; 62613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 62623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GLPositionCase::getCaseTypeName (CaseType type) 62643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 62653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (type) 62663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 62673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_VS_TO_TCS: return "gl_position_vs_to_tcs"; 62683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_TCS_TO_TES: return "gl_position_tcs_to_tes"; 62693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case CASETYPE_VS_TO_TCS_TO_TES: return "gl_position_vs_to_tcs_to_tes"; 62703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 62713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); return DE_NULL; 62723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 62733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 62743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GLPositionCase::init (void) 62763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 62773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkTessellationSupport(m_context); 62783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkRenderTargetSize(m_context.getRenderTarget(), RENDER_SIZE); 62793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool vsToTCS = m_caseType == CASETYPE_VS_TO_TCS || m_caseType == CASETYPE_VS_TO_TCS_TO_TES; 62813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool tcsToTES = m_caseType == CASETYPE_TCS_TO_TES || m_caseType == CASETYPE_VS_TO_TCS_TO_TES; 62823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string tesIn0 = tcsToTES ? "gl_in[0].gl_Position" : "in_te_attr[0]"; 62843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string tesIn1 = tcsToTES ? "gl_in[1].gl_Position" : "in_te_attr[1]"; 62853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string tesIn2 = tcsToTES ? "gl_in[2].gl_Position" : "in_te_attr[2]"; 62863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = SharedPtr<const ShaderProgram>(new ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 62883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource ("#version 310 es\n" 62893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 62903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_v_attr;\n" 62913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + string(!vsToTCS ? "out highp vec4 in_tc_attr;\n" : "") + 62923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 62933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 62943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 62953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + (vsToTCS ? "gl_Position" : "in_tc_attr") + " = in_v_attr;\n" 62963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 62973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 62983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource ("#version 310 es\n" 62993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 63003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (vertices = 3) out;\n" 63023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + string(!vsToTCS ? "in highp vec4 in_tc_attr[];\n" : "") + 63043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (!tcsToTES ? "out highp vec4 in_te_attr[];\n" : "") + 63063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 63083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 63093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + (tcsToTES ? "gl_out[gl_InvocationID].gl_Position" : "in_te_attr[gl_InvocationID]") + " = " 63103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (vsToTCS ? "gl_in[gl_InvocationID].gl_Position" : "in_tc_attr[gl_InvocationID]") + ";\n" 63113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 2.0;\n" 63133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 3.0;\n" 63143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 4.0;\n" 63163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 5.0;\n" 63173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 6.0;\n" 63183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 7.0;\n" 63193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 63203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource ("#version 310 es\n" 63223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 63233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + getTessellationEvaluationInLayoutString(TESSPRIMITIVETYPE_TRIANGLES) + 63253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (!tcsToTES ? "in highp vec4 in_te_attr[];\n" : "") + 63273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 in_f_color;\n" 63293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 63313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 63323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " highp vec2 xy = gl_TessCoord.x * " + tesIn0 + ".xy\n" 63333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + gl_TessCoord.y * " + tesIn1 + ".xy\n" 63343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " + gl_TessCoord.z * " + tesIn2 + ".xy;\n" 63353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(xy, 0.0, 1.0);\n" 63363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " in_f_color = vec4(" + tesIn0 + ".z + " + tesIn1 + ".w,\n" 63373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + tesIn2 + ".z + " + tesIn0 + ".w,\n" 63383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " + tesIn1 + ".z + " + tesIn2 + ".w,\n" 63393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " 1.0);\n" 63403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n") 63413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource ("#version 310 es\n" 63433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (location = 0) out mediump vec4 o_color;\n" 63453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 in_f_color;\n" 63473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 63483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 63493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 63503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " o_color = in_f_color;\n" 63513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"))); 63523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 63543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 63553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_FAIL("Program compilation failed"); 63563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 63573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GLPositionCase::deinit (void) 63593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 63603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program.clear(); 63613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 63623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLPositionCase::IterateResult GLPositionCase::iterate (void) 63643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 63653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 63663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RenderContext& renderCtx = m_context.getRenderContext(); 63673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const RandomViewport viewport (renderCtx.getRenderTarget(), RENDER_SIZE, RENDER_SIZE, deStringHash(getName())); 63683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = renderCtx.getFunctions(); 63693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 programGL = m_program->getProgram(); 63703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const float attributes[3*4] = 63723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 63733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -0.8f, -0.7f, 0.1f, 0.7f, 63743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -0.5f, 0.4f, 0.2f, 0.5f, 63753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.3f, 0.2f, 0.3f, 0.45f 63763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 63773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(programGL); 63793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry setViewport(gl, viewport); 63803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 3); 63813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 63833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 63843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Note: input data for in_v_attr:\n" << arrayStr(attributes, 4) << TestLog::EndMessage; 63863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 63883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArrayBinding bindings[] = { glu::va::Float("in_v_attr", 4, 3, 0, &attributes[0]) }; 63893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(renderCtx, programGL, DE_LENGTH_OF_ARRAY(bindings), &bindings[0], glu::pr::Patches(3)); 63903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 63923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Surface pixels = getPixels(renderCtx, viewport); 63933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::TextureLevel reference = getPNG(m_testCtx.getArchive(), m_referenceImagePath.c_str()); 63943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool success = tcu::fuzzyCompare(log, "ImageComparison", "Image Comparison", reference.getAccess(), pixels.getAccess(), 0.02f, tcu::COMPARE_LOG_RESULT); 63953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 63963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!success) 63973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 63983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 63993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 64003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 64013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 64023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 64033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 64043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 64053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 64063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 64073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6408c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass LimitQueryCase : public TestCase 6409c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6410c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6411c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry LimitQueryCase (Context& context, const char* name, const char* desc, glw::GLenum target, int minValue); 6412c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6413c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6414c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6415c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const glw::GLenum m_target; 6416c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const int m_minValue; 6417c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6418c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6419c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryLimitQueryCase::LimitQueryCase (Context& context, const char* name, const char* desc, glw::GLenum target, int minValue) 6420c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase (context, name, desc) 6421c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_target (target) 6422c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_minValue (minValue) 6423c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6424c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6425c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6426c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryLimitQueryCase::IterateResult LimitQueryCase::iterate (void) 6427c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6428c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6429c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6430c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6431c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6432c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6433c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6434c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER); 6435c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6436c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6437c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries"); 6438c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_BOOLEAN); 6439c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_INTEGER64); 6440c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_target, m_minValue, QUERY_FLOAT); 6441c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6442c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6443c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6444c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6445c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6446c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6447c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass CombinedUniformLimitCase : public TestCase 6448c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6449c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6450c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry CombinedUniformLimitCase (Context& context, const char* name, const char* desc, glw::GLenum combined, glw::GLenum numBlocks, glw::GLenum defaultComponents); 6451c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6452c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6453c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6454c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const glw::GLenum m_combined; 6455c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const glw::GLenum m_numBlocks; 6456c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const glw::GLenum m_defaultComponents; 6457c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6458c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6459c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryCombinedUniformLimitCase::CombinedUniformLimitCase (Context& context, const char* name, const char* desc, glw::GLenum combined, glw::GLenum numBlocks, glw::GLenum defaultComponents) 6460c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase (context, name, desc) 6461c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_combined (combined) 6462c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_numBlocks (numBlocks) 6463c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_defaultComponents (defaultComponents) 6464c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6465c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6466c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6467c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryCombinedUniformLimitCase::IterateResult CombinedUniformLimitCase::iterate (void) 6468c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6469c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6470c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6471c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6472c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6473c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6474c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6475c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6476c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message 6477c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << "The minimum value of " << glu::getGettableStateStr(m_combined) 6478c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << " is " << glu::getGettableStateStr(m_numBlocks) 6479c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << " x MAX_UNIFORM_BLOCK_SIZE / 4 + " 6480c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::getGettableStateStr(m_defaultComponents) 6481c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::EndMessage; 6482c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6483c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlocks; 6484c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetIntegerv(m_numBlocks, &maxUniformBlocks); 6485c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv"); 6486c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6487c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry StateQueryMemoryWriteGuard<glw::GLint> maxUniformBlockSize; 6488c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &maxUniformBlockSize); 6489c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv"); 6490c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6491c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry StateQueryMemoryWriteGuard<glw::GLint> maxUniformComponents; 6492c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetIntegerv(m_defaultComponents, &maxUniformComponents); 6493c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glGetIntegerv"); 6494c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6495c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (maxUniformBlocks.verifyValidity(result) && maxUniformBlockSize.verifyValidity(result) && maxUniformComponents.verifyValidity(result)) 6496c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6497c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const int limit = ((int)maxUniformBlocks) * ((int)maxUniformBlockSize) / 4 + (int)maxUniformComponents; 6498c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_INTEGER); 6499c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6500c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6501c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Types", "Alternative queries"); 6502c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_BOOLEAN); 6503c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_INTEGER64); 6504c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, m_combined, limit, QUERY_FLOAT); 6505c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6506c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6507c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6508c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6509c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6510c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6511c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6512c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass PatchVerticesStateCase : public TestCase 6513c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6514c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6515c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry PatchVerticesStateCase (Context& context, const char* name, const char* desc); 6516c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6517c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6518c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6519c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6520c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryPatchVerticesStateCase::PatchVerticesStateCase (Context& context, const char* name, const char* desc) 6521c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase(context, name, desc) 6522c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6523c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6524c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6525c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryPatchVerticesStateCase::IterateResult PatchVerticesStateCase::iterate (void) 6526c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6527c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6528c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6529c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6530c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6531c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6532c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6533c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6534c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // initial 6535c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6536c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "initial", "Initial value"); 6537c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6538c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateInteger(result, gl, GL_PATCH_VERTICES, 3, QUERY_INTEGER); 6539c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6540c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6541c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // bind 6542c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6543c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "set", "After set"); 6544c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6545c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glPatchParameteri(GL_PATCH_VERTICES, 22); 6546c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "glPatchParameteri"); 6547c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6548c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateInteger(result, gl, GL_PATCH_VERTICES, 22, QUERY_INTEGER); 6549c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6550c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "Types", "Alternative queries"); 6551c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_BOOLEAN); 6552c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_INTEGER64); 6553c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateIntegerMin(result, gl, GL_PATCH_VERTICES, 22, QUERY_FLOAT); 6554c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6555c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6556c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6557c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6558c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6559c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6560c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6561c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass PrimitiveRestartForPatchesSupportedCase : public TestCase 6562c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6563c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6564c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry PrimitiveRestartForPatchesSupportedCase (Context& context, const char* name, const char* desc); 6565c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6566c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6567c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6568c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6569c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryPrimitiveRestartForPatchesSupportedCase::PrimitiveRestartForPatchesSupportedCase (Context& context, const char* name, const char* desc) 6570c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase(context, name, desc) 6571c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6572c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6573c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6574c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryPrimitiveRestartForPatchesSupportedCase::IterateResult PrimitiveRestartForPatchesSupportedCase::iterate (void) 6575c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6576c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6577c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6578c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6579c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6580c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry QueriedState state; 6581c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6582c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6583c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6584c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryState(result, gl, QUERY_BOOLEAN, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state); 6585c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6586c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!state.isUndefined()) 6587c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6588c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection subsection(m_testCtx.getLog(), "Types", "Alternative types"); 6589c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_INTEGER); 6590c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_INTEGER64); 6591c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateBoolean(result, gl, GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED, state.getBoolAccess(), QUERY_FLOAT); 6592c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6593c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6594c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6595c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6596c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6597c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6598c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessProgramQueryCase : public TestCase 6599c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6600c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6601c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessProgramQueryCase (Context& context, const char* name, const char* desc); 6602c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6603c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getVertexSource (void) const; 6604c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getFragmentSource (void) const; 6605c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getTessCtrlSource (const char* globalLayouts) const; 6606c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getTessEvalSource (const char* globalLayouts) const; 6607c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6608c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6609c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessProgramQueryCase::TessProgramQueryCase (Context& context, const char* name, const char* desc) 6610c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase(context, name, desc) 6611c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6612c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6613c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6614c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string TessProgramQueryCase::getVertexSource (void) const 6615c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6616c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 6617c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 6618c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 6619c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_Position = vec4(float(gl_VertexID), float(gl_VertexID / 2), 0.0, 1.0);\n" 6620c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 6621c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6622c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6623c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string TessProgramQueryCase::getFragmentSource (void) const 6624c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6625c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 6626c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "layout (location = 0) out mediump vec4 o_color;\n" 6627c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 6628c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 6629c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 6630c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 6631c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6632c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6633c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string TessProgramQueryCase::getTessCtrlSource (const char* globalLayouts) const 6634c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6635c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 6636c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "#extension GL_EXT_tessellation_shader : require\n" 6637c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry + std::string(globalLayouts) + ";\n" 6638c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 6639c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 6640c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 6641c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[0] = 2.8;\n" 6642c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[1] = 2.8;\n" 6643c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[0] = 2.8;\n" 6644c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[1] = 2.8;\n" 6645c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[2] = 2.8;\n" 6646c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[3] = 2.8;\n" 6647c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 6648c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6649c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6650c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string TessProgramQueryCase::getTessEvalSource (const char* globalLayouts) const 6651c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6652c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 6653c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "#extension GL_EXT_tessellation_shader : require\n" 6654c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry + std::string(globalLayouts) + ";\n" 6655c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 6656c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 6657c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n" 6658c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + gl_TessCoord.y * gl_in[1].gl_Position\n" 6659c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + gl_TessCoord.y * gl_in[2].gl_Position\n" 6660c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + gl_TessCoord.z * gl_in[3].gl_Position;\n" 6661c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 6662c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6663c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6664c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessControlOutputVerticesCase : public TessProgramQueryCase 6665c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6666c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6667c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessControlOutputVerticesCase (Context& context, const char* name, const char* desc); 6668c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6669c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6670c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6671c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6672c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessControlOutputVerticesCase::TessControlOutputVerticesCase (Context& context, const char* name, const char* desc) 6673c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TessProgramQueryCase(context, name, desc) 6674c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6675c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6676c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6677c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessControlOutputVerticesCase::IterateResult TessControlOutputVerticesCase::iterate (void) 6678c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6679c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6680c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6681c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6682c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6683c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6684c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource("layout(vertices=4) out")) 6685c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource("layout(triangles) in"))); 6686c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6687c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6688c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6689c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry throw tcu::TestError("failed to build program"); 6690c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6691c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6692c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6693c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6694c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6695c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6696c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 4, QUERY_PROGRAM_INTEGER); 6697c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6698c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6699c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6700c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6701c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6702c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6703c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessGenModeQueryCase : public TessProgramQueryCase 6704c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6705c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6706c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessGenModeQueryCase (Context& context, const char* name, const char* desc); 6707c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6708c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6709c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6710c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6711c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenModeQueryCase::TessGenModeQueryCase (Context& context, const char* name, const char* desc) 6712c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TessProgramQueryCase(context, name, desc) 6713c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6714c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6715c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6716c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenModeQueryCase::IterateResult TessGenModeQueryCase::iterate (void) 6717c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6718c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6719c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6720c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6721c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry static const struct 6722c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6723c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* description; 6724c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* layout; 6725c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLenum mode; 6726c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } s_modes[] = 6727c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6728c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Triangles", "layout(triangles) in", GL_TRIANGLES }, 6729c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Isolines", "layout(isolines) in", GL_ISOLINES }, 6730c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Quads", "layout(quads) in", GL_QUADS }, 6731c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry }; 6732c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6733c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6734c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6735c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6736c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx) 6737c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6738c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Type", s_modes[ndx].description); 6739c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6740c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6741c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6742c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6743c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out")) 6744c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout))); 6745c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6746c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6747c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6748c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 6749c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6750c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, s_modes[ndx].mode, QUERY_PROGRAM_INTEGER); 6751c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6752c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6753c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6754c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6755c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6756c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6757c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessGenSpacingQueryCase : public TessProgramQueryCase 6758c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6759c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6760c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessGenSpacingQueryCase (Context& context, const char* name, const char* desc); 6761c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6762c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6763c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6764c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6765c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenSpacingQueryCase::TessGenSpacingQueryCase (Context& context, const char* name, const char* desc) 6766c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TessProgramQueryCase(context, name, desc) 6767c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6768c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6769c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6770c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenSpacingQueryCase::IterateResult TessGenSpacingQueryCase::iterate (void) 6771c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6772c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6773c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6774c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6775c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry static const struct 6776c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6777c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* description; 6778c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* layout; 6779c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLenum spacing; 6780c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } s_modes[] = 6781c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6782c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Default spacing", "layout(triangles) in", GL_EQUAL }, 6783c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Equal spacing", "layout(triangles, equal_spacing) in", GL_EQUAL }, 6784c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Fractional even spacing", "layout(triangles, fractional_even_spacing) in", GL_FRACTIONAL_EVEN }, 6785c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Fractional odd spacing", "layout(triangles, fractional_odd_spacing) in", GL_FRACTIONAL_ODD }, 6786c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry }; 6787c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6788c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6789c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6790c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6791c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx) 6792c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6793c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Type", s_modes[ndx].description); 6794c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6795c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6796c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6797c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6798c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out")) 6799c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout))); 6800c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6801c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6802c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6803c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 6804c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6805c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, s_modes[ndx].spacing, QUERY_PROGRAM_INTEGER); 6806c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6807c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6808c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6809c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6810c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6811c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6812c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessGenVertexOrderQueryCase : public TessProgramQueryCase 6813c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6814c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6815c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessGenVertexOrderQueryCase (Context& context, const char* name, const char* desc); 6816c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6817c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6818c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6819c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6820c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenVertexOrderQueryCase::TessGenVertexOrderQueryCase (Context& context, const char* name, const char* desc) 6821c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TessProgramQueryCase(context, name, desc) 6822c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6823c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6824c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6825c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenVertexOrderQueryCase::IterateResult TessGenVertexOrderQueryCase::iterate (void) 6826c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6827c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6828c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6829c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6830c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry static const struct 6831c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6832c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* description; 6833c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* layout; 6834c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLenum order; 6835c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } s_modes[] = 6836c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6837c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Default order", "layout(triangles) in", GL_CCW }, 6838c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "CW order", "layout(triangles, cw) in", GL_CW }, 6839c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "CCW order", "layout(triangles, ccw) in", GL_CCW }, 6840c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry }; 6841c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6842c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6843c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6844c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6845c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx) 6846c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6847c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Type", s_modes[ndx].description); 6848c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6849c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6850c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6851c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6852c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out")) 6853c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout))); 6854c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6855c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6856c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6857c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 6858c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6859c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, s_modes[ndx].order, QUERY_PROGRAM_INTEGER); 6860c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6861c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6862c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6863c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6864c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6865c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6866c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass TessGenPointModeQueryCase : public TessProgramQueryCase 6867c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6868c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6869c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry TessGenPointModeQueryCase (Context& context, const char* name, const char* desc); 6870c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6871c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6872c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6873c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6874c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenPointModeQueryCase::TessGenPointModeQueryCase (Context& context, const char* name, const char* desc) 6875c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TessProgramQueryCase(context, name, desc) 6876c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6877c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6878c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6879c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryTessGenPointModeQueryCase::IterateResult TessGenPointModeQueryCase::iterate (void) 6880c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6881c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6882c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6883c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6884c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry static const struct 6885c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6886c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* description; 6887c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const char* layout; 6888c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLenum mode; 6889c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } s_modes[] = 6890c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6891c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Default mode", "layout(triangles) in", GL_FALSE }, 6892c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { "Point mode", "layout(triangles, point_mode) in", GL_TRUE }, 6893c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry }; 6894c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6895c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6896c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6897c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6898c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_modes); ++ndx) 6899c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6900c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section(m_testCtx.getLog(), "Type", s_modes[ndx].description); 6901c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6902c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6903c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6904c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6905c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource("layout(vertices=6) out")) 6906c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource(s_modes[ndx].layout))); 6907c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6908c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6909c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6910c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 6911c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6912c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, s_modes[ndx].mode, QUERY_PROGRAM_INTEGER); 6913c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6914c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6915c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 6916c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 6917c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6918c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6919c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass ReferencedByTessellationQueryCase : public TestCase 6920c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6921c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 6922c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry ReferencedByTessellationQueryCase (Context& context, const char* name, const char* desc, bool isCtrlCase); 6923c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 6924c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry void init (void); 6925c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 6926c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6927c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getVertexSource (void) const; 6928c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getFragmentSource (void) const; 6929c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getTessCtrlSource (void) const; 6930c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::string getTessEvalSource (void) const; 6931c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6932c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const bool m_isCtrlCase; 6933c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 6934c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6935c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryReferencedByTessellationQueryCase::ReferencedByTessellationQueryCase (Context& context, const char* name, const char* desc, bool isCtrlCase) 6936c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase (context, name, desc) 6937c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry , m_isCtrlCase (isCtrlCase) 6938c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6939c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6940c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6941c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryvoid ReferencedByTessellationQueryCase::init (void) 6942c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6943c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 6944c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 6945c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6946c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryReferencedByTessellationQueryCase::IterateResult ReferencedByTessellationQueryCase::iterate (void) 6947c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 6948c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 6949c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 6950c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 6951c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::VertexSource(getVertexSource()) 6952c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::FragmentSource(getFragmentSource()) 6953c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(getTessCtrlSource()) 6954c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationEvaluationSource(getTessEvalSource())); 6955c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6956c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 6957c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6958c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 6959c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 6960c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 6961c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6962c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6963c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const deUint32 props[1] = { (deUint32)((m_isCtrlCase) ? (GL_REFERENCED_BY_TESS_CONTROL_SHADER) : (GL_REFERENCED_BY_TESS_EVALUATION_SHADER)) }; 6964c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6965c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6966c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "UnreferencedUniform", "Unreferenced uniform u_unreferenced"); 6967c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry deUint32 resourcePos; 6968c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLsizei length = 0; 6969c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLint referenced = 0; 6970c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6971c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_unreferenced"); 6972c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "u_unreferenced resource index: " << resourcePos << tcu::TestLog::EndMessage; 6973c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6974c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (resourcePos == GL_INVALID_INDEX) 6975c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("resourcePos was GL_INVALID_INDEX"); 6976c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 6977c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6978c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetProgramResourceiv(program.getProgram(), GL_UNIFORM, resourcePos, 1, props, 1, &length, &referenced); 6979c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() 6980c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::Message 6981c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << "Query " << glu::getProgramResourcePropertyStr(props[0]) 6982c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced) 6983c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::EndMessage; 6984c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6985c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "query resource"); 6986c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6987c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (length == 0 || referenced != GL_FALSE) 6988c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("expected GL_FALSE"); 6989c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6990c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 6991c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6992c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 6993c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "ReferencedUniform", "Referenced uniform u_referenced"); 6994c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry deUint32 resourcePos; 6995c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLsizei length = 0; 6996c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLint referenced = 0; 6997c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 6998c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_UNIFORM, "u_referenced"); 6999c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "u_referenced resource index: " << resourcePos << tcu::TestLog::EndMessage; 7000c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7001c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (resourcePos == GL_INVALID_INDEX) 7002c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("resourcePos was GL_INVALID_INDEX"); 7003c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 7004c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7005c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetProgramResourceiv(program.getProgram(), GL_UNIFORM, resourcePos, 1, props, 1, &length, &referenced); 7006c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() 7007c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::Message 7008c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << "Query " << glu::getProgramResourcePropertyStr(props[0]) 7009c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced) 7010c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::EndMessage; 7011c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7012c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLU_EXPECT_NO_ERROR(gl.glGetError(), "query resource"); 7013c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7014c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (length == 0 || referenced != GL_TRUE) 7015c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("expected GL_TRUE"); 7016c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7017c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7018c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7019c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7020c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 7021c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 7022c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7023c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7024c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string ReferencedByTessellationQueryCase::getVertexSource (void) const 7025c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7026c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 7027c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 7028c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 7029c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_Position = vec4(float(gl_VertexID), float(gl_VertexID / 2), 0.0, 1.0);\n" 7030c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 7031c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7032c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7033c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string ReferencedByTessellationQueryCase::getFragmentSource (void) const 7034c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7035c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return "#version 310 es\n" 7036c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "layout (location = 0) out mediump vec4 o_color;\n" 7037c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 7038c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 7039c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 7040c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 7041c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7042c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7043c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string ReferencedByTessellationQueryCase::getTessCtrlSource (void) const 7044c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7045c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::ostringstream buf; 7046c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry buf << "#version 310 es\n" 7047c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "#extension GL_EXT_tessellation_shader : require\n" 7048c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "layout(vertices = 3) out;\n" 7049c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "uniform highp vec4 " << ((m_isCtrlCase) ? ("u_referenced") : ("u_unreferenced")) << ";\n" 7050c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 7051c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 7052c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " vec4 offset = " << ((m_isCtrlCase) ? ("u_referenced") : ("u_unreferenced")) << ";\n" 7053c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position + offset;\n" 7054c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[0] = 2.8;\n" 7055c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[1] = 2.8;\n" 7056c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[0] = 2.8;\n" 7057c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[1] = 2.8;\n" 7058c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[2] = 2.8;\n" 7059c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[3] = 2.8;\n" 7060c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 7061c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return buf.str(); 7062c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7063c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7064c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrystd::string ReferencedByTessellationQueryCase::getTessEvalSource (void) const 7065c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7066c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry std::ostringstream buf; 7067c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry buf << "#version 310 es\n" 7068c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "#extension GL_EXT_tessellation_shader : require\n" 7069c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "layout(triangles) in;\n" 7070c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "uniform highp vec4 " << ((m_isCtrlCase) ? ("u_unreferenced") : ("u_referenced")) << ";\n" 7071c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 7072c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 7073c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " vec4 offset = " << ((m_isCtrlCase) ? ("u_unreferenced") : ("u_referenced")) << ";\n" 7074c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position\n" 7075c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + gl_TessCoord.y * gl_in[1].gl_Position\n" 7076c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + gl_TessCoord.z * gl_in[2].gl_Position\n" 7077c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " + offset;\n" 7078c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 7079c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7080c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return buf.str(); 7081c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7082c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7083c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryclass IsPerPatchQueryCase : public TestCase 7084c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7085c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyrypublic: 7086c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IsPerPatchQueryCase (Context& context, const char* name, const char* desc); 7087c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryprivate: 7088c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry void init (void); 7089c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry IterateResult iterate (void); 7090c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry}; 7091c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7092c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryIsPerPatchQueryCase::IsPerPatchQueryCase (Context& context, const char* name, const char* desc) 7093c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry : TestCase(context, name, desc) 7094c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7095c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7096c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7097c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyryvoid IsPerPatchQueryCase::init (void) 7098c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7099c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry checkTessellationSupport(m_context); 7100c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7101c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7102c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko PöyryIsPerPatchQueryCase::IterateResult IsPerPatchQueryCase::iterate (void) 7103c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry{ 7104c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry static const char* const s_controlSource = "#version 310 es\n" 7105c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "#extension GL_EXT_tessellation_shader : require\n" 7106c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "layout(vertices = 3) out;\n" 7107c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "patch out highp vec4 v_perPatch;\n" 7108c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "out highp vec4 v_perVertex[];\n" 7109c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "void main (void)\n" 7110c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "{\n" 7111c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 7112c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " v_perPatch = gl_in[0].gl_Position;\n" 7113c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " v_perVertex[gl_InvocationID] = -gl_in[gl_InvocationID].gl_Position;\n" 7114c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[0] = 2.8;\n" 7115c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelInner[1] = 2.8;\n" 7116c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[0] = 2.8;\n" 7117c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[1] = 2.8;\n" 7118c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[2] = 2.8;\n" 7119c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry " gl_TessLevelOuter[3] = 2.8;\n" 7120c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry "}\n"; 7121c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: "); 7122c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog()); 7123c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() 7124c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::TessellationControlSource(s_controlSource) 7125c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << glu::ProgramSeparable(true)); 7126c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7127c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.enableLogging(true); 7128c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7129c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << program; 7130c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (!program.isOk()) 7131c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("failed to build program"); 7132c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 7133c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7134c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const deUint32 props[1] = { GL_IS_PER_PATCH }; 7135c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7136c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7137c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "PerPatchOutput", "Per patch v_perPatch"); 7138c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry deUint32 resourcePos; 7139c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLsizei length = 0; 7140c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLint referenced = 0; 7141c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7142c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_PROGRAM_OUTPUT, "v_perPatch"); 7143c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "v_perPatch resource index: " << resourcePos << tcu::TestLog::EndMessage; 7144c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7145c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (resourcePos == GL_INVALID_INDEX) 7146c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("resourcePos was GL_INVALID_INDEX"); 7147c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 7148c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7149c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetProgramResourceiv(program.getProgram(), GL_PROGRAM_OUTPUT, resourcePos, 1, props, 1, &length, &referenced); 7150c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() 7151c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::Message 7152c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << "Query " << glu::getProgramResourcePropertyStr(props[0]) 7153c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced) 7154c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::EndMessage; 7155c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7156c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "query resource"); 7157c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7158c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (length == 0 || referenced != GL_TRUE) 7159c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("expected GL_TRUE"); 7160c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7161c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7162c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7163c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7164c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry const tcu::ScopedLogSection section (m_testCtx.getLog(), "PerVertexhOutput", "Per vertex v_perVertex"); 7165c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry deUint32 resourcePos; 7166c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLsizei length = 0; 7167c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry glw::GLint referenced = 0; 7168c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7169c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry resourcePos = gl.glGetProgramResourceIndex(program.getProgram(), GL_PROGRAM_OUTPUT, "v_perVertex"); 7170c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() << tcu::TestLog::Message << "v_perVertex resource index: " << resourcePos << tcu::TestLog::EndMessage; 7171c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7172c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (resourcePos == GL_INVALID_INDEX) 7173c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("resourcePos was GL_INVALID_INDEX"); 7174c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry else 7175c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 7176c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry gl.glGetProgramResourceiv(program.getProgram(), GL_PROGRAM_OUTPUT, resourcePos, 1, props, 1, &length, &referenced); 7177c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry m_testCtx.getLog() 7178c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::Message 7179c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << "Query " << glu::getProgramResourcePropertyStr(props[0]) 7180c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << ", got " << length << " value(s), value[0] = " << glu::getBooleanStr(referenced) 7181c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry << tcu::TestLog::EndMessage; 7182c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7183c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry GLU_EXPECT_NO_ERROR(gl.glGetError(), "query resource"); 7184c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7185c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry if (length == 0 || referenced != GL_FALSE) 7186c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.fail("expected GL_FALSE"); 7187c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7188c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7189c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7190c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7191c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry result.setTestContextResult(m_testCtx); 7192c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry return STOP; 7193c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry} 7194c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 71953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 71963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 71973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationTests::TessellationTests (Context& context) 71983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "tessellation", "Tessellation Tests") 71993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 72003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 72013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationTests::~TessellationTests (void) 72033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 72043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 72053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessellationTests::init (void) 72073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 72083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7209c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry tcu::TestCaseGroup* const queryGroup = new tcu::TestCaseGroup(m_testCtx, "state_query", "Query tests"); 7210c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry addChild(queryGroup); 7211c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7212c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // new limits 7213c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_patch_vertices", "Test MAX_PATCH_VERTICES", GL_MAX_PATCH_VERTICES, 32)); 7214c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_gen_level", "Test MAX_TESS_GEN_LEVEL", GL_MAX_TESS_GEN_LEVEL, 64)); 7215c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_uniform_components", "Test MAX_TESS_CONTROL_UNIFORM_COMPONENTS", GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS, 1024)); 7216c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_uniform_components", "Test MAX_TESS_EVALUATION_UNIFORM_COMPONENTS", GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS, 1024)); 7217c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_texture_image_units", "Test MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS", GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, 16)); 7218c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_texture_image_units", "Test MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS", GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, 16)); 7219c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_output_components", "Test MAX_TESS_CONTROL_OUTPUT_COMPONENTS", GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS, 128)); 7220c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_patch_components", "Test MAX_TESS_PATCH_COMPONENTS", GL_MAX_TESS_PATCH_COMPONENTS, 120)); 7221c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_total_output_components", "Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS", GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS, 4096)); 7222c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_output_components", "Test MAX_TESS_EVALUATION_OUTPUT_COMPONENTS", GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS, 128)); 7223c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_uniform_blocks", "Test MAX_TESS_CONTROL_UNIFORM_BLOCKS", GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, 12)); 7224c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_uniform_blocks", "Test MAX_TESS_EVALUATION_UNIFORM_BLOCKS", GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, 12)); 7225c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_input_components", "Test MAX_TESS_CONTROL_INPUT_COMPONENTS", GL_MAX_TESS_CONTROL_INPUT_COMPONENTS, 128)); 7226c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_input_components", "Test MAX_TESS_EVALUATION_INPUT_COMPONENTS", GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS, 128)); 7227c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_atomic_counter_buffers", "Test MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS", GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS, 0)); 7228c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_atomic_counter_buffers", "Test MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS", GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS, 0)); 7229c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_atomic_counters", "Test MAX_TESS_CONTROL_ATOMIC_COUNTERS", GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, 0)); 7230c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_atomic_counters", "Test MAX_TESS_EVALUATION_ATOMIC_COUNTERS", GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, 0)); 7231c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_image_uniforms", "Test MAX_TESS_CONTROL_IMAGE_UNIFORMS", GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS, 0)); 7232c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_image_uniforms", "Test MAX_TESS_EVALUATION_IMAGE_UNIFORMS", GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS, 0)); 7233c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_shader_storage_blocks", "Test MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS", GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, 0)); 7234c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_shader_storage_blocks", "Test MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS", GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, 0)); 7235c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7236c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // modified limits 7237c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_uniform_buffer_bindings", "Test MAX_UNIFORM_BUFFER_BINDINGS", GL_MAX_UNIFORM_BUFFER_BINDINGS, 72)); 7238c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_combined_uniform_blocks", "Test MAX_COMBINED_UNIFORM_BLOCKS", GL_MAX_COMBINED_UNIFORM_BLOCKS, 60)); 7239c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new LimitQueryCase(m_context, "max_combined_texture_image_units", "Test MAX_COMBINED_TEXTURE_IMAGE_UNITS", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 96)); 7240c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7241c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // combined limits 7242c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new CombinedUniformLimitCase(m_context, "max_combined_tess_control_uniform_components", "Test MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS", GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS, GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS)); 7243c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new CombinedUniformLimitCase(m_context, "max_combined_tess_evaluation_uniform_components", "Test MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS", GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS, GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS)); 7244c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7245c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // features 7246c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new PrimitiveRestartForPatchesSupportedCase(m_context, "primitive_restart_for_patches_supported", "Test PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED")); 7247c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7248c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // states 7249c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new PatchVerticesStateCase(m_context, "patch_vertices", "Test PATCH_VERTICES")); 7250c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7251c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // program states 7252c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new TessControlOutputVerticesCase (m_context, "tess_control_output_vertices", "Test TESS_CONTROL_OUTPUT_VERTICES")); 7253c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new TessGenModeQueryCase (m_context, "tess_gen_mode", "Test TESS_GEN_MODE")); 7254c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new TessGenSpacingQueryCase (m_context, "tess_gen_spacing", "Test TESS_GEN_SPACING")); 7255c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new TessGenVertexOrderQueryCase (m_context, "tess_gen_vertex_order", "Test TESS_GEN_VERTEX_ORDER")); 7256c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new TessGenPointModeQueryCase (m_context, "tess_gen_point_mode", "Test TESS_GEN_POINT_MODE")); 7257c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7258c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry // resource queries 7259c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new ReferencedByTessellationQueryCase (m_context, "referenced_by_tess_control_shader", "Test REFERENCED_BY_TESS_CONTROL_SHADER", true)); 7260c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new ReferencedByTessellationQueryCase (m_context, "referenced_by_tess_evaluation_shader", "Test REFERENCED_BY_TESS_EVALUATION_SHADER", false)); 7261c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry queryGroup->addChild(new IsPerPatchQueryCase (m_context, "is_per_patch", "Test IS_PER_PATCH")); 7262c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry } 7263c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry 7264c423ce6164cdd88c8c3e47bec4ec34476743042aJarkko Pöyry { 72653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const tessCoordGroup = new TestCaseGroup(m_context, "tesscoord", "Get tessellation coordinates with transform feedback and validate them"); 72663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(tessCoordGroup); 72673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 72693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 72703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 72713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 72733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoordGroup->addChild(new TessCoordCase(m_context, 72743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string() + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getSpacingModeShaderName((SpacingMode)spacingI)).c_str(), "", 72753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType, (SpacingMode)spacingI)); 72763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 72773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 72783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 72803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const windingGroup = new TestCaseGroup(m_context, "winding", "Test the cw and ccw input layout qualifiers"); 72813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(windingGroup); 72823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 72843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 72853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 72863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitiveType == TESSPRIMITIVETYPE_ISOLINES) 72873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 72883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int windingI = 0; windingI < WINDING_LAST; windingI++) 72903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 72913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding winding = (Winding)windingI; 72923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry windingGroup->addChild(new WindingCase(m_context, (string() + getTessPrimitiveTypeShaderName(primitiveType) + "_" + getWindingShaderName(winding)).c_str(), "", primitiveType, winding)); 72933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 72943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 72953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 72963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 72973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 72983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const shaderInputOutputGroup = new TestCaseGroup(m_context, "shader_input_output", "Test tessellation control and evaluation shader inputs and outputs"); 72993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(shaderInputOutputGroup); 73003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 73033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int inPatchSize; 73053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int outPatchSize; 73063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } patchVertexCountCases[] = 73073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5, 10 }, 73093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10, 5 } 73103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 73113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(patchVertexCountCases); caseNdx++) 73133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int inSize = patchVertexCountCases[caseNdx].inPatchSize; 73153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outSize = patchVertexCountCases[caseNdx].outPatchSize; 73163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = "patch_vertices_" + de::toString(inSize) + "_in_" + de::toString(outSize) + "_out"; 73183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry shaderInputOutputGroup->addChild(new PatchVertexCountCase(m_context, caseName.c_str(), "Test input and output patch vertex counts", inSize, outSize, 73203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("data/tessellation/" + caseName + "_ref.png").c_str())); 73213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int caseTypeI = 0; caseTypeI < PerPatchDataCase::CASETYPE_LAST; caseTypeI++) 73253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const PerPatchDataCase::CaseType caseType = (PerPatchDataCase::CaseType)caseTypeI; 73273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const caseName = PerPatchDataCase::getCaseTypeName(caseType); 73283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry shaderInputOutputGroup->addChild(new PerPatchDataCase(m_context, caseName, PerPatchDataCase::getCaseTypeDescription(caseType), caseType, 73303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PerPatchDataCase::caseTypeUsesRefImageFromFile(caseType) ? (string() + "data/tessellation/" + caseName + "_ref.png").c_str() : DE_NULL)); 73313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int caseTypeI = 0; caseTypeI < GLPositionCase::CASETYPE_LAST; caseTypeI++) 73343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLPositionCase::CaseType caseType = (GLPositionCase::CaseType)caseTypeI; 73363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const caseName = GLPositionCase::getCaseTypeName(caseType); 73373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry shaderInputOutputGroup->addChild(new GLPositionCase(m_context, caseName, "", caseType, "data/tessellation/gl_position_ref.png")); 73393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry shaderInputOutputGroup->addChild(new BarrierCase(m_context, "barrier", "Basic barrier usage", "data/tessellation/barrier_ref.png")); 73423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const miscDrawGroup = new TestCaseGroup(m_context, "misc_draw", "Miscellaneous draw-result-verifying cases"); 73463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(miscDrawGroup); 73473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 73493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 73513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitiveType == TESSPRIMITIVETYPE_ISOLINES) 73523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 73533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const primTypeName = getTessPrimitiveTypeShaderName(primitiveType); 73553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 73573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = string() + "fill_cover_" + primTypeName + "_" + getSpacingModeShaderName((SpacingMode)spacingI); 73593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry miscDrawGroup->addChild(new BasicTriangleFillCoverCase(m_context, 73613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseName.c_str(), "Check that there are no obvious gaps in the triangle-filled area of a tessellated shape", 73623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType, (SpacingMode)spacingI, 73633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("data/tessellation/" + caseName + "_ref").c_str())); 73643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 73683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 73703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitiveType == TESSPRIMITIVETYPE_ISOLINES) 73713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 73723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const primTypeName = getTessPrimitiveTypeShaderName(primitiveType); 73743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 73763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = string() + "fill_overlap_" + primTypeName + "_" + getSpacingModeShaderName((SpacingMode)spacingI); 73783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry miscDrawGroup->addChild(new BasicTriangleFillNonOverlapCase(m_context, 73803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseName.c_str(), "Check that there are no obvious triangle overlaps in the triangle-filled area of a tessellated shape", 73813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType, (SpacingMode)spacingI, 73823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("data/tessellation/" + caseName + "_ref").c_str())); 73833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 73873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = string() + "isolines_" + getSpacingModeShaderName((SpacingMode)spacingI); 73893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry miscDrawGroup->addChild(new IsolinesRenderCase(m_context, 73913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseName.c_str(), "Basic isolines render test", 73923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (SpacingMode)spacingI, 73933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ("data/tessellation/" + caseName + "_ref").c_str())); 73943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 73963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 73973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 73983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const commonEdgeGroup = new TestCaseGroup(m_context, "common_edge", "Draw multiple adjacent shapes and check that no cracks appear between them"); 73993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(commonEdgeGroup); 74003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int caseTypeI = 0; caseTypeI < CommonEdgeCase::CASETYPE_LAST; caseTypeI++) 74023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 74043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CommonEdgeCase::CaseType caseType = (CommonEdgeCase::CaseType)caseTypeI; 74063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 74073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (primitiveType == TESSPRIMITIVETYPE_ISOLINES) 74083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 74093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 74113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode spacing = (SpacingMode)spacingI; 74133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string caseName = (string() + getTessPrimitiveTypeShaderName(primitiveType) 74143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + "_" + getSpacingModeShaderName(spacing) 74153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (caseType == CommonEdgeCase::CASETYPE_BASIC ? "" 74163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : caseType == CommonEdgeCase::CASETYPE_PRECISE ? "_precise" 74173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL)); 74183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry commonEdgeGroup->addChild(new CommonEdgeCase(m_context, caseName.c_str(), "", primitiveType, spacing, caseType)); 74203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const fractionalSpacingModeGroup = new TestCaseGroup(m_context, "fractional_spacing", "Test fractional spacing modes"); 74273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(fractionalSpacingModeGroup); 74283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fractionalSpacingModeGroup->addChild(new FractionalSpacingModeCase(m_context, "odd", "", SPACINGMODE_FRACTIONAL_ODD)); 74303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fractionalSpacingModeGroup->addChild(new FractionalSpacingModeCase(m_context, "even", "", SPACINGMODE_FRACTIONAL_EVEN)); 74313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const primitiveDiscardGroup = new TestCaseGroup(m_context, "primitive_discard", "Test primitive discard with relevant outer tessellation level <= 0.0"); 74353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(primitiveDiscardGroup); 74363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 74383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 74403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int windingI = 0; windingI < WINDING_LAST; windingI++) 74423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++) 74443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 74463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode spacing = (SpacingMode)spacingI; 74473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding winding = (Winding)windingI; 74483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool usePointMode = usePointModeI != 0; 74493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveDiscardGroup->addChild(new PrimitiveDiscardCase(m_context, (string() + getTessPrimitiveTypeShaderName(primitiveType) 74513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + "_" + getSpacingModeShaderName(spacing) 74523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + "_" + getWindingShaderName(winding) 74533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry + (usePointMode ? "_point_mode" : "")).c_str(), "", 74543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType, spacing, winding, usePointMode)); 74553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 74603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invarianceGroup = new TestCaseGroup(m_context, "invariance", "Test tessellation invariance rules"); 74633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invariantPrimitiveSetGroup = new TestCaseGroup(m_context, "primitive_set", "Test invariance rule #1"); 74653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invariantOuterEdgeGroup = new TestCaseGroup(m_context, "outer_edge_division", "Test invariance rule #2"); 74663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const symmetricOuterEdgeGroup = new TestCaseGroup(m_context, "outer_edge_symmetry", "Test invariance rule #3"); 74673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const outerEdgeVertexSetIndexIndependenceGroup = new TestCaseGroup(m_context, "outer_edge_index_independence", "Test invariance rule #4"); 74683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invariantTriangleSetGroup = new TestCaseGroup(m_context, "triangle_set", "Test invariance rule #5"); 74693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invariantInnerTriangleSetGroup = new TestCaseGroup(m_context, "inner_triangle_set", "Test invariance rule #6"); 74703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const invariantOuterTriangleSetGroup = new TestCaseGroup(m_context, "outer_triangle_set", "Test invariance rule #7"); 74713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const tessCoordComponentRangeGroup = new TestCaseGroup(m_context, "tess_coord_component_range", "Test invariance rule #8, first part"); 74723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const oneMinusTessCoordComponentGroup = new TestCaseGroup(m_context, "one_minus_tess_coord_component", "Test invariance rule #8, second part"); 74733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(invarianceGroup); 74753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(invariantPrimitiveSetGroup); 74763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(invariantOuterEdgeGroup); 74773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(symmetricOuterEdgeGroup); 74783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(outerEdgeVertexSetIndexIndependenceGroup); 74793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(invariantTriangleSetGroup); 74803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(invariantInnerTriangleSetGroup); 74813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(invariantOuterTriangleSetGroup); 74823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(tessCoordComponentRangeGroup); 74833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invarianceGroup->addChild(oneMinusTessCoordComponentGroup); 74843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 74863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 74883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string primName = getTessPrimitiveTypeShaderName(primitiveType); 74893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool triOrQuad = primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS; 74903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int spacingI = 0; spacingI < SPACINGMODE_LAST; spacingI++) 74923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const SpacingMode spacing = (SpacingMode)spacingI; 74943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string primSpacName = primName + "_" + getSpacingModeShaderName(spacing); 74953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 74963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (triOrQuad) 74973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 74983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invariantOuterEdgeGroup->addChild (new InvariantOuterEdgeCase (m_context, primSpacName.c_str(), "", primitiveType, spacing)); 74993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invariantTriangleSetGroup->addChild (new InvariantTriangleSetCase (m_context, primSpacName.c_str(), "", primitiveType, spacing)); 75003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invariantInnerTriangleSetGroup->addChild(new InvariantInnerTriangleSetCase (m_context, primSpacName.c_str(), "", primitiveType, spacing)); 75013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invariantOuterTriangleSetGroup->addChild(new InvariantOuterTriangleSetCase (m_context, primSpacName.c_str(), "", primitiveType, spacing)); 75023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int windingI = 0; windingI < WINDING_LAST; windingI++) 75053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const Winding winding = (Winding)windingI; 75073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string primSpacWindName = primSpacName + "_" + getWindingShaderName(winding); 75083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int usePointModeI = 0; usePointModeI <= 1; usePointModeI++) 75103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool usePointMode = usePointModeI != 0; 75123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const string primSpacWindPointName = primSpacWindName + (usePointMode ? "_point_mode" : ""); 75133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry invariantPrimitiveSetGroup->addChild (new InvariantPrimitiveSetCase (m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode)); 75153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry symmetricOuterEdgeGroup->addChild (new SymmetricOuterEdgeCase (m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode)); 75163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessCoordComponentRangeGroup->addChild (new TessCoordComponentRangeCase (m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode)); 75173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry oneMinusTessCoordComponentGroup->addChild (new OneMinusTessCoordComponentCase (m_context, primSpacWindPointName.c_str(), "", primitiveType, spacing, winding, usePointMode)); 75183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (triOrQuad) 75203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry outerEdgeVertexSetIndexIndependenceGroup->addChild(new OuterEdgeVertexSetIndexIndependenceCase(m_context, primSpacWindPointName.c_str(), "", 75213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry primitiveType, spacing, winding, usePointMode)); 75223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75298cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry static const struct 75308cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 75318cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const char* name; 75328cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry const char* description; 75338cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry UserDefinedIOCase::IOType ioType; 75348cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry } ioCases[] = 75358cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { 75368cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_patch", "Per-patch TCS outputs", UserDefinedIOCase::IO_TYPE_PER_PATCH }, 75378cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_patch_array", "Per-patch array TCS outputs", UserDefinedIOCase::IO_TYPE_PER_PATCH_ARRAY }, 75388cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_patch_block", "Per-patch TCS outputs in IO block", UserDefinedIOCase::IO_TYPE_PER_PATCH_BLOCK }, 75398cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_patch_block_array", "Per-patch TCS outputs in IO block array", UserDefinedIOCase::IO_TYPE_PER_PATCH_BLOCK_ARRAY }, 75408cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_vertex", "Per-vertex TCS outputs", UserDefinedIOCase::IO_TYPE_PER_VERTEX }, 75418cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry { "per_vertex_block", "Per-vertex TCS outputs in IO block", UserDefinedIOCase::IO_TYPE_PER_VERTEX_BLOCK }, 75428cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry }; 75438cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry 75443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const userDefinedIOGroup = new TestCaseGroup(m_context, "user_defined_io", "Test non-built-in per-patch and per-vertex inputs and outputs"); 75453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(userDefinedIOGroup); 75463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75478cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ioCases); ++ndx) 75483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75498cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry TestCaseGroup* const ioTypeGroup = new TestCaseGroup(m_context, ioCases[ndx].name, ioCases[ndx].description); 75503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry userDefinedIOGroup->addChild(ioTypeGroup); 75513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int vertexArraySizeI = 0; vertexArraySizeI < UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_LAST; vertexArraySizeI++) 75533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const UserDefinedIOCase::VertexIOArraySize vertexArraySize = (UserDefinedIOCase::VertexIOArraySize)vertexArraySizeI; 75553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestCaseGroup* const vertexArraySizeGroup = new TestCaseGroup(m_context, 75563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_IMPLICIT 75573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ? "vertex_io_array_size_implicit" 75583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_EXPLICIT_SHADER_BUILTIN 75593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ? "vertex_io_array_size_shader_builtin" 75603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : vertexArraySizeI == UserDefinedIOCase::VERTEX_IO_ARRAY_SIZE_EXPLICIT_QUERY 75613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ? "vertex_io_array_size_query" 75623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : DE_NULL, 75633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ""); 75643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ioTypeGroup->addChild(vertexArraySizeGroup); 75653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveTypeI = 0; primitiveTypeI < TESSPRIMITIVETYPE_LAST; primitiveTypeI++) 75673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 75683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessPrimitiveType primitiveType = (TessPrimitiveType)primitiveTypeI; 75698cd63a217cae5f39d8d88b87e2cfdfb1a8325638Jarkko Pöyry vertexArraySizeGroup->addChild(new UserDefinedIOCase(m_context, getTessPrimitiveTypeShaderName(primitiveType), "", primitiveType, ioCases[ndx].ioType, vertexArraySize, 75703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string() + "data/tessellation/user_defined_io_" + getTessPrimitiveTypeShaderName(primitiveType) + "_ref.png").c_str())); 75713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 757418c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry 757518c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry { 757618c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry TestCaseGroup* const negativeGroup = new TestCaseGroup(m_context, "negative", "Negative cases"); 757718c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry gls::ShaderLibrary shaderLibrary (m_testCtx, m_context.getRenderContext(), m_context.getContextInfo()); 757818c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry const std::vector<tcu::TestNode*> children = shaderLibrary.loadShaderFile("shaders/tessellation_negative_user_defined_io.test"); 757918c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry 758018c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry userDefinedIOGroup->addChild(negativeGroup); 758118c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry 758218c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry for (int i = 0; i < (int)children.size(); i++) 758318c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry negativeGroup->addChild(children[i]); 758418c15f928a710db86e7e374b478faea3b198afc3Jarkko Pöyry } 75853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 75863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 75873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 75883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 75893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 75903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 7591