1abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*------------------------------------------------------------------------ 2abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Vulkan Conformance Tests 3abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * ------------------------ 4abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 5abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2014 The Android Open Source Project 6abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Copyright (c) 2016 The Khronos Group Inc. 7abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 8abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Licensed under the Apache License, Version 2.0 (the "License"); 9abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * you may not use this file except in compliance with the License. 10abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * You may obtain a copy of the License at 11abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 12abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * http://www.apache.org/licenses/LICENSE-2.0 13abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 14abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Unless required by applicable law or agreed to in writing, software 15abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * distributed under the License is distributed on an "AS IS" BASIS, 16abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * See the License for the specific language governing permissions and 18abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * limitations under the License. 19abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 20abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*! 21abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \file 22abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Tessellation Invariance Tests 23abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 24abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 25abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationInvarianceTests.hpp" 26abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTestCaseUtil.hpp" 27abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vktTessellationUtil.hpp" 28abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 29abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuTestLog.hpp" 30abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "tcuVectorUtil.hpp" 31abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 32abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkDefs.hpp" 33abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkQueryUtil.hpp" 34abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkBuilderUtil.hpp" 35abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkImageUtil.hpp" 36abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "vkTypeUtil.hpp" 37abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 38abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deUniquePtr.hpp" 39abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deStringUtil.hpp" 40abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include "deRandom.hpp" 41abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 42abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include <string> 43abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include <vector> 44abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski#include <set> 45abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 46abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace vkt 47abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 48abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace tessellation 49abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 50abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 51abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiusing namespace vk; 52abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 53abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace 54abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 55abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 56abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskienum Constants 57abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 58abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski NUM_TESS_LEVELS = 6, // two inner and four outer levels 59abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 60abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 61abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskienum WindingUsage 62abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 63abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski WINDING_USAGE_CCW = 0, 64abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski WINDING_USAGE_CW, 65abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski WINDING_USAGE_VARY, 66abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 67abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski WINDING_USAGE_LAST, 68abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 69abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 70abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline WindingUsage getWindingUsage (const Winding winding) 71abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 72abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const WindingUsage usage = winding == WINDING_CCW ? WINDING_USAGE_CCW : 73abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski winding == WINDING_CW ? WINDING_USAGE_CW : WINDING_USAGE_LAST; 74abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(usage != WINDING_USAGE_LAST); 75abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return usage; 76abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 77abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 78abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<Winding> getWindingCases (const WindingUsage windingUsage) 79abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 80abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<Winding> cases; 81abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski switch (windingUsage) 82abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 83abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case WINDING_USAGE_CCW: 84abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(WINDING_CCW); 85abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 86abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case WINDING_USAGE_CW: 87abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(WINDING_CW); 88abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 89abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case WINDING_USAGE_VARY: 90abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(WINDING_CCW); 91abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(WINDING_CW); 92abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 93abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski default: 94abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 95abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 96abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 97abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return cases; 98abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 99abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskienum PointModeUsage 101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski POINT_MODE_USAGE_DONT_USE = 0, 103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski POINT_MODE_USAGE_USE, 104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski POINT_MODE_USAGE_VARY, 105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski POINT_MODE_USAGE_LAST, 107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline PointModeUsage getPointModeUsage (const bool usePointMode) 110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return usePointMode ? POINT_MODE_USAGE_USE : POINT_MODE_USAGE_DONT_USE; 112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<bool> getUsePointModeCases (const PointModeUsage pointModeUsage) 115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<bool> cases; 117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski switch (pointModeUsage) 118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case POINT_MODE_USAGE_DONT_USE: 120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(false); 121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case POINT_MODE_USAGE_USE: 123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(true); 124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case POINT_MODE_USAGE_VARY: 126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(false); 127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski cases.push_back(true); 128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski default: 130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return cases; 134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Data captured in the shader per output primitive (in geometry stage). 137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct PerPrimitive 138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deInt32 patchPrimitiveID; //!< gl_PrimitiveID in tessellation evaluation shader 140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deInt32 primitiveID; //!< ID of an output primitive in geometry shader (user-defined) 141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deInt32 unused_padding[2]; 143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::Vec4 tessCoord[3]; //!< 3 coords for triangles/quads, 2 for isolines, 1 for point mode. Vec4 due to alignment. 145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitypedef std::vector<PerPrimitive> PerPrimitiveVec; 148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline bool byPatchPrimitiveID (const PerPrimitive& a, const PerPrimitive& b) 150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return a.patchPrimitiveID < b.patchPrimitiveID; 152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline std::string getProgramName (const std::string& baseName, const Winding winding, const bool usePointMode) 155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream str; 157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski str << baseName << "_" << getWindingShaderName(winding) << (usePointMode ? "_point_mode" : ""); 158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return str.str(); 159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline std::string getProgramName (const std::string& baseName, const bool usePointMode) 162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream str; 164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski str << baseName << (usePointMode ? "_point_mode" : ""); 165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return str.str(); 166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline std::string getProgramDescription (const Winding winding, const bool usePointMode) 169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream str; 171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski str << "winding mode " << getWindingShaderName(winding) << ", " << (usePointMode ? "" : "don't ") << "use point mode"; 172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return str.str(); 173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename T, int N> 176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<T> arrayToVector (const T (&arr)[N]) 177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return std::vector<T>(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr)); 179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename T, int N> 182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiT arrayMax (const T (&arr)[N]) 183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return *std::max_element(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr)); 185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <int Size> 188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline tcu::Vector<bool, Size> singleTrueMask (int index) 189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(de::inBounds(index, 0, Size)); 191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::Vector<bool, Size> result; 192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result[index] = true; 193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename ContainerT, typename T> 197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline bool contains (const ContainerT& c, const T& key) 198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return c.find(key) != c.end(); 200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename SeqT, int Size, typename Pred> 203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass LexCompare 204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 206abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski LexCompare (void) : m_pred(Pred()) {} 207abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 208abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const SeqT& a, const SeqT& b) const 209abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 210abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < Size; ++i) 211abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 212abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_pred(a[i], b[i])) 213abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 214abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_pred(b[i], a[i])) 215abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 216abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 217abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 218abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 219abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 220abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate: 221abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Pred m_pred; 222abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 223abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 224abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <int Size> 225abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass VecLexLessThan : public LexCompare<tcu::Vector<float, Size>, Size, std::less<float> > 226abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 227abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 228abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 229abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Add default programs for invariance tests. 230abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Creates multiple shader programs for combinations of winding and point mode. 231abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! mirrorCoords - special mode where some tessellation coordinates are mirrored in tessellation evaluation shader. 232abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! This is used by symmetric outer edge test. 233abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid addDefaultPrograms (vk::SourceCollections& programCollection, 234abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const TessPrimitiveType primitiveType, 235abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const SpacingMode spacingMode, 236abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const WindingUsage windingUsage, 237abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PointModeUsage pointModeUsage, 238abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool mirrorCoords = false) 239abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 240abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Vertex shader 241abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 242abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 243abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 244abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 245abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) in highp float in_v_attr;\n" 246abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) out highp float in_tc_attr;\n" 247abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 248abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 249abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 250abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " in_tc_attr = in_v_attr;\n" 251abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 252abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 253abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 254abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 255abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 256abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Tessellation control shader 257abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 258abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 259abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 260abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "#extension GL_EXT_tessellation_shader : require\n" 261abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 262abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(vertices = 1) out;\n" 263abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 264abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) in highp float in_tc_attr[];\n" 265abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 266abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 267abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 268abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelInner[0] = in_tc_attr[0];\n" 269abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelInner[1] = in_tc_attr[1];\n" 270abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 271abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 272abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 273abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 274abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 275abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 276abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 277abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()); 278abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 279abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 280abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::string perVertexInterfaceBlock = \ 281abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski "VertexData {\n" // no in/out qualifier 282abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski " vec4 in_gs_tessCoord;\n" // w component is used by mirroring test 283abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski " int in_gs_primitiveID;\n" 284abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski "}"; // no newline nor semicolon 285abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 286abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Alternative tess coordinates handling code 287abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream tessEvalCoordSrc; 288abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (mirrorCoords) 289abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski switch (primitiveType) 290abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 291abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_TRIANGLES: 292abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessEvalCoordSrc << " float x = gl_TessCoord.x;\n" 293abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " float y = gl_TessCoord.y;\n" 294abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " float z = gl_TessCoord.z;\n" 295abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 296abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " // Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n" 297abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " ib_out.in_gs_tessCoord = z == 0.0 && x > 0.5 && x != 1.0 ? vec4(1.0-x, 1.0-y, 0.0, 1.0)\n" 298abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : y == 0.0 && z > 0.5 && z != 1.0 ? vec4(1.0-x, 0.0, 1.0-z, 1.0)\n" 299abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : x == 0.0 && y > 0.5 && y != 1.0 ? vec4( 0.0, 1.0-y, 1.0-z, 1.0)\n" 300abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : vec4(x, y, z, 0.0);\n"; 301abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 302abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_QUADS: 303abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessEvalCoordSrc << " float x = gl_TessCoord.x;\n" 304abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " float y = gl_TessCoord.y;\n" 305abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 306abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " // Mirror one half of each outer edge onto the other half, except the endpoints (because they belong to two edges)\n" 307abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " ib_out.in_gs_tessCoord = (x == 0.0 || x == 1.0) && y > 0.5 && y != 1.0 ? vec4( x, 1.0-y, 0.0, 1.0)\n" 308abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : (y == 0.0 || y == 1.0) && x > 0.5 && x != 1.0 ? vec4(1.0-x, y, 0.0, 1.0)\n" 309abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : vec4(x, y, 0.0, 0.0);\n"; 310abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 311abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_ISOLINES: 312abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessEvalCoordSrc << " float x = gl_TessCoord.x;\n" 313abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " float y = gl_TessCoord.y;\n" 314abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 315abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " // Mirror one half of each outer edge onto the other half\n" 316abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " ib_out.in_gs_tessCoord = (x == 0.0 || x == 1.0) && y > 0.5 ? vec4(x, 1.0-y, 0.0, 1.0)\n" 317abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " : vec4(x, y, 0.0, 0.0);\n"; 318abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 319abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski default: 320abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 321abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return; 322abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 323abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 324abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessEvalCoordSrc << " ib_out.in_gs_tessCoord = vec4(gl_TessCoord, 0.0);\n"; 325abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 326abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<Winding> windingCases = getWindingCases(windingUsage); 327abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<bool> usePointModeCases = getUsePointModeCases(pointModeUsage); 328abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 329abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (std::vector<Winding>::const_iterator windingIter = windingCases.begin(); windingIter != windingCases.end(); ++windingIter) 330abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (std::vector<bool>::const_iterator usePointModeIter = usePointModeCases.begin(); usePointModeIter != usePointModeCases.end(); ++usePointModeIter) 331abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 332abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Tessellation evaluation shader 333abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 334abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 335abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 336abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "#extension GL_EXT_tessellation_shader : require\n" 337abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 338abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(" << getTessPrimitiveTypeShaderName(primitiveType) << ", " 339abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getSpacingModeShaderName(spacingMode) << ", " 340abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getWindingShaderName(*windingIter) 341abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << (*usePointModeIter ? ", point_mode" : "") << ") in;\n" 342abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 343abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) out " << perVertexInterfaceBlock << " ib_out;\n" 344abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 345abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 346abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 347abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tessEvalCoordSrc.str() 348abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " ib_out.in_gs_primitiveID = gl_PrimitiveID;\n" 349abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 350abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 351abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add(getProgramName("tese", *windingIter, *usePointModeIter)) << glu::TessellationEvaluationSource(src.str()); 352abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 353abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } // for windingNdx, usePointModeNdx 354abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 355abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Geometry shader: data is captured here. 356abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 357abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (std::vector<bool>::const_iterator usePointModeIter = usePointModeCases.begin(); usePointModeIter != usePointModeCases.end(); ++usePointModeIter) 358abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 359abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numVertices = numVerticesPerPrimitive(primitiveType, *usePointModeIter); // Primitives that the tessellated patch comprises of. 360abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 361abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 362abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 363abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "#extension GL_EXT_geometry_shader : require\n" 364abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 365abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(" << getGeometryShaderInputPrimitiveTypeShaderName(primitiveType, *usePointModeIter) << ") in;\n" 366abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(" << getGeometryShaderOutputPrimitiveTypeShaderName(primitiveType, *usePointModeIter) << ", max_vertices = " << numVertices << ") out;\n" 367abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 368abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) in " << perVertexInterfaceBlock << " ib_in[];\n" 369abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 370abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "struct PerPrimitive {\n" 371abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int patchPrimitiveID;\n" 372abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int primitiveID;\n" 373abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " vec4 tessCoord[3];\n" 374abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "};\n" 375abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 376abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(set = 0, binding = 0, std430) coherent restrict buffer Output {\n" 377abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int numPrimitives;\n" 378abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " PerPrimitive primitive[];\n" 379abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "} sb_out;\n" 380abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 381abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 382abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 383abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int index = atomicAdd(sb_out.numPrimitives, 1);\n" 384abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " sb_out.primitive[index].patchPrimitiveID = ib_in[0].in_gs_primitiveID;\n" 385abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " sb_out.primitive[index].primitiveID = index;\n"; 386abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numVertices; ++i) 387abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << " sb_out.primitive[index].tessCoord[" << i << "] = ib_in[" << i << "].in_gs_tessCoord;\n"; 388abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numVertices; ++i) 389abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << "\n" 390abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_Position = vec4(0.0);\n" 391abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " EmitVertex();\n"; 392abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << "}\n"; 393abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 394abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add(getProgramName("geom", *usePointModeIter)) << glu::GeometrySource(src.str()); 395abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 396abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 397abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 398abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 399abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! A description of an outer edge of a triangle, quad or isolines. 400abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! An outer edge can be described by the index of a u/v/w coordinate 401abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! and the coordinate's value along that edge. 402abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct OuterEdgeDescription 403abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 404abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int constantCoordinateIndex; 405abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski float constantCoordinateValueChoices[2]; 406abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int numConstantCoordinateValueChoices; 407abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 408abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription (const int i, const float c0) : constantCoordinateIndex(i), numConstantCoordinateValueChoices(1) { constantCoordinateValueChoices[0] = c0; } 409abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription (const int i, const float c0, const float c1) : constantCoordinateIndex(i), numConstantCoordinateValueChoices(2) { constantCoordinateValueChoices[0] = c0; constantCoordinateValueChoices[1] = c1; } 410abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 411abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::string description (void) const 412abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 413abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const char* const coordinateNames[] = { "u", "v", "w" }; 414abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::string result; 415abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numConstantCoordinateValueChoices; ++i) 416abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result += std::string() + (i > 0 ? " or " : "") + coordinateNames[constantCoordinateIndex] + "=" + de::toString(constantCoordinateValueChoices[i]); 417abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 418abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 419abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 420abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool contains (const tcu::Vec3& v) const 421abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 422abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numConstantCoordinateValueChoices; ++i) 423abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (v[constantCoordinateIndex] == constantCoordinateValueChoices[i]) 424abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 425abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 426abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 427abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 428abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 429abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<OuterEdgeDescription> outerEdgeDescriptions (const TessPrimitiveType primType) 430abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 431abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const OuterEdgeDescription triangleOuterEdgeDescriptions[3] = 432abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 433abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(0, 0.0f), 434abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(1, 0.0f), 435abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(2, 0.0f) 436abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 437abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 438abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const OuterEdgeDescription quadOuterEdgeDescriptions[4] = 439abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 440abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(0, 0.0f), 441abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(1, 0.0f), 442abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(0, 1.0f), 443abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(1, 1.0f) 444abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 445abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 446abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const OuterEdgeDescription isolinesOuterEdgeDescriptions[1] = 447abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 448abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDescription(0, 0.0f, 1.0f), 449abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 450abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 451abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski switch (primType) 452abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 453abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_TRIANGLES: return arrayToVector(triangleOuterEdgeDescriptions); 454abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_QUADS: return arrayToVector(quadOuterEdgeDescriptions); 455abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case TESSPRIMITIVETYPE_ISOLINES: return arrayToVector(isolinesOuterEdgeDescriptions); 456abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 457abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski default: 458abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 459abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return std::vector<OuterEdgeDescription>(); 460abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 461abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 462abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 463abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace InvariantOuterEdge 464abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 465abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 466abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct CaseDefinition 467abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 468abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessPrimitiveType primitiveType; 469abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski SpacingMode spacingMode; 470abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Winding winding; 471abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool usePointMode; 472abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 473abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 474abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitypedef std::set<tcu::Vec3, VecLexLessThan<3> > Vec3Set; 475abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 476abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<float> generateRandomPatchTessLevels (const int numPatches, const int constantOuterLevelIndex, const float constantOuterLevel, de::Random& rnd) 477abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 478abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<float> tessLevels(numPatches*NUM_TESS_LEVELS); 479abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 480abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int patchNdx = 0; patchNdx < numPatches; ++patchNdx) 481abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 482abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski float* const inner = &tessLevels[patchNdx*NUM_TESS_LEVELS + 0]; 483abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski float* const outer = &tessLevels[patchNdx*NUM_TESS_LEVELS + 2]; 484abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 485abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int j = 0; j < 2; ++j) 486abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski inner[j] = rnd.getFloat(1.0f, 62.0f); 487abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int j = 0; j < 4; ++j) 488abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outer[j] = j == constantOuterLevelIndex ? constantOuterLevel : rnd.getFloat(1.0f, 62.0f); 489abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 490abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 491abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tessLevels; 492abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 493abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 494abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<float> generatePatchTessLevels (const int numPatches, const int constantOuterLevelIndex, const float constantOuterLevel) 495abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 496abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::Random rnd(123); 497abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return generateRandomPatchTessLevels(numPatches, constantOuterLevelIndex, constantOuterLevel, rnd); 498abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 499abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 500abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint multiplePatchReferencePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* levels, int numPatches) 501abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 502abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int result = 0; 503abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int patchNdx = 0; patchNdx < numPatches; ++patchNdx) 504abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result += referencePrimitiveCount(primitiveType, spacingMode, usePointMode, &levels[NUM_TESS_LEVELS*patchNdx + 0], &levels[NUM_TESS_LEVELS*patchNdx + 2]); 505abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 506abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 507abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 508abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate<std::size_t N> 509abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiint computeMaxPrimitiveCount (const int numPatchesToDraw, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float (&singleOuterEdgeLevels)[N]) 510abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 511abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int outerEdgeIndex = 0; // outer-edge index doesn't affect vertex count 512abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<float> patchTessLevels = generatePatchTessLevels(numPatchesToDraw, outerEdgeIndex, arrayMax(singleOuterEdgeLevels)); 513abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return multiplePatchReferencePrimitiveCount(primitiveType, spacingMode, usePointMode, &patchTessLevels[0], numPatchesToDraw); 514abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 515abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 516abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid logOuterTessellationLevel (tcu::TestLog& log, const float tessLevel, const OuterEdgeDescription& edgeDesc) 517abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 518abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 519abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Testing with outer tessellation level " << tessLevel << " for the " << edgeDesc.description() << " edge, and with various levels for other edges, and with all programs" 520abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 521abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 522abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 523abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid logPrimitiveCountError (tcu::TestLog& log, const int numPatchesToDraw, int numPrimitives, const int refNumPrimitives, const std::vector<float>& patchTessLevels) 524abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 525abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 526abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Failure: the number of generated primitives is " << numPrimitives << ", expected at least " << refNumPrimitives 527abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 528abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 529abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (numPatchesToDraw == 1) 530abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 531abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Note: rendered one patch; tessellation levels are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n" 532abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << containerStr(patchTessLevels, NUM_TESS_LEVELS) 533abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 534abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 535abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 536abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Note: rendered " << numPatchesToDraw << " patches in one draw call; " 537abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "tessellation levels for each patch are (in order [inner0, inner1, outer0, outer1, outer2, outer3]):\n" 538abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << containerStr(patchTessLevels, NUM_TESS_LEVELS) 539abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 540abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 541abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 542abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass BaseTestInstance : public TestInstance 543abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 544abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 545abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski struct DrawResult 546abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 547abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool success; 548abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int refNumPrimitives; 549abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int numPrimitiveVertices; 550abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deInt32 numPrimitives; 551abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski PerPrimitiveVec primitives; 552abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 553abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 554abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski BaseTestInstance (Context& context, const CaseDefinition caseDef, const int numPatchesToDraw); 555abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DrawResult draw (const deUint32 vertexCount, const std::vector<float>& patchTessLevels, const Winding winding, const bool usePointMode); 556abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski void uploadVertexAttributes (const std::vector<float>& vertexData); 557abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 558abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 559abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const float m_singleOuterEdgeLevels[]; 560abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 561abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 562abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int m_numPatchesToDraw; 563abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkFormat m_vertexFormat; 564abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deUint32 m_vertexStride; 565abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<OuterEdgeDescription> m_edgeDescriptions; 566abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int m_maxNumPrimitivesInDrawCall; 567abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize m_vertexDataSizeBytes; 568abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer m_vertexBuffer; 569abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int m_resultBufferPrimitiveDataOffset; 570abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize m_resultBufferSizeBytes; 571abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer m_resultBuffer; 572abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkDescriptorSetLayout> m_descriptorSetLayout; 573abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkDescriptorPool> m_descriptorPool; 574abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkDescriptorSet> m_descriptorSet; 575abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkRenderPass> m_renderPass; 576abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkFramebuffer> m_framebuffer; 577abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkPipelineLayout> m_pipelineLayout; 578abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkCommandPool> m_cmdPool; 579abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Unique<VkCommandBuffer> m_cmdBuffer; 580abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 581abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 582abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiconst float BaseTestInstance::m_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 }; 583abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 584abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiBaseTestInstance::BaseTestInstance (Context& context, const CaseDefinition caseDef, const int numPatchesToDraw) 585abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : TestInstance (context) 586abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_caseDef (caseDef) 587abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_numPatchesToDraw (numPatchesToDraw) 588abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_vertexFormat (VK_FORMAT_R32_SFLOAT) 589abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_vertexStride (tcu::getPixelSize(mapVkFormat(m_vertexFormat))) 590abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_edgeDescriptions (outerEdgeDescriptions(m_caseDef.primitiveType)) 591abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_maxNumPrimitivesInDrawCall (computeMaxPrimitiveCount(m_numPatchesToDraw, caseDef.primitiveType, caseDef.spacingMode, caseDef.usePointMode, m_singleOuterEdgeLevels)) 592abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_vertexDataSizeBytes (NUM_TESS_LEVELS * m_numPatchesToDraw * m_vertexStride) 593abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_vertexBuffer (m_context.getDeviceInterface(), m_context.getDevice(), m_context.getDefaultAllocator(), 594abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski makeBufferCreateInfo(m_vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible) 5956e5ef4c51158771e71f72c70980b4dbd78f011f2Pyry Haulos , m_resultBufferPrimitiveDataOffset ((int)sizeof(deInt32) * 4) 596abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_resultBufferSizeBytes (m_resultBufferPrimitiveDataOffset + m_maxNumPrimitivesInDrawCall * sizeof(PerPrimitive)) 597abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_resultBuffer (m_context.getDeviceInterface(), m_context.getDevice(), m_context.getDefaultAllocator(), 598abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski makeBufferCreateInfo(m_resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible) 599abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_descriptorSetLayout (DescriptorSetLayoutBuilder() 600abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT) 601abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(m_context.getDeviceInterface(), m_context.getDevice())) 602abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_descriptorPool (DescriptorPoolBuilder() 603abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 604abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(m_context.getDeviceInterface(), m_context.getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)) 605abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_descriptorSet (makeDescriptorSet(m_context.getDeviceInterface(), m_context.getDevice(), *m_descriptorPool, *m_descriptorSetLayout)) 606abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_renderPass (makeRenderPassWithoutAttachments (m_context.getDeviceInterface(), m_context.getDevice())) 607abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_framebuffer (makeFramebufferWithoutAttachments(m_context.getDeviceInterface(), m_context.getDevice(), *m_renderPass)) 608abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_pipelineLayout (makePipelineLayout (m_context.getDeviceInterface(), m_context.getDevice(), *m_descriptorSetLayout)) 609abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_cmdPool (makeCommandPool (m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueueFamilyIndex())) 61055dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi , m_cmdBuffer (allocateCommandBuffer (m_context.getDeviceInterface(), m_context.getDevice(), *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)) 611abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 612abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), 613abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski FEATURE_TESSELLATION_SHADER | FEATURE_GEOMETRY_SHADER | FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 614abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 615abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(m_resultBuffer.get(), 0ull, m_resultBufferSizeBytes); 616abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 617abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DescriptorSetUpdateBuilder() 618abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo) 619abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .update(m_context.getDeviceInterface(), m_context.getDevice()); 620abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 621abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 622abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! patchTessLevels are tessellation levels for all drawn patches. 623abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiBaseTestInstance::DrawResult BaseTestInstance::draw (const deUint32 vertexCount, const std::vector<float>& patchTessLevels, const Winding winding, const bool usePointMode) 624abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 625abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DeviceInterface& vk = m_context.getDeviceInterface(); 626abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDevice device = m_context.getDevice(); 627abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkQueue queue = m_context.getUniversalQueue(); 628abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 629abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkPipeline> pipeline(GraphicsPipelineBuilder() 630abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setPatchControlPoints (NUM_TESS_LEVELS) 631abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setVertexInputSingleAttribute(m_vertexFormat, m_vertexStride) 632abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert"), DE_NULL) 633abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_context.getBinaryCollection().get("tesc"), DE_NULL) 634abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get(getProgramName("tese", winding, usePointMode)), DE_NULL) 635abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, m_context.getBinaryCollection().get(getProgramName("geom", usePointMode)), DE_NULL) 636abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build (vk, device, *m_pipelineLayout, *m_renderPass)); 637abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 638abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 639abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = m_resultBuffer.getAllocation(); 640abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(m_resultBufferSizeBytes)); 641abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), m_resultBufferSizeBytes); 642abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 643abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 644abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginCommandBuffer(vk, *m_cmdBuffer); 645abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginRenderPassWithRasterizationDisabled(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer); 646abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 647abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 648abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL); 649abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 650abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize vertexBufferOffset = 0ull; 651abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset); 652abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 653abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 654abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdDraw(*m_cmdBuffer, vertexCount, 1u, 0u, 0u); 655abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endRenderPass(vk, *m_cmdBuffer); 656abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 657abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 658abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( 659abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *m_resultBuffer, 0ull, m_resultBufferSizeBytes); 660abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 661abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 662abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL); 663abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 664abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 665abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endCommandBuffer(vk, *m_cmdBuffer); 666abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski submitCommandsAndWait(vk, device, queue, *m_cmdBuffer); 667abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 668abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Read back and check results 669abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 670abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& resultAlloc = m_resultBuffer.getAllocation(); 671abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), m_resultBufferSizeBytes); 672abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 673abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DrawResult result; 674abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.success = true; 675abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.refNumPrimitives = multiplePatchReferencePrimitiveCount(m_caseDef.primitiveType, m_caseDef.spacingMode, usePointMode, &patchTessLevels[0], m_numPatchesToDraw); 676abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.numPrimitiveVertices = numVerticesPerPrimitive(m_caseDef.primitiveType, usePointMode); 677abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.numPrimitives = *static_cast<deInt32*>(resultAlloc.getHostPtr()); 678abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.primitives = sorted(readInterleavedData<PerPrimitive>(result.numPrimitives, resultAlloc.getHostPtr(), m_resultBufferPrimitiveDataOffset, sizeof(PerPrimitive)), 679abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski byPatchPrimitiveID); 680abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 681abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // If this fails then we didn't read all vertices from shader and test must be changed to allow more. 682abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(result.numPrimitives <= m_maxNumPrimitivesInDrawCall); 683abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 684abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = m_context.getTestContext().getLog(); 685abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (result.numPrimitives != result.refNumPrimitives) 686abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 687abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski logPrimitiveCountError(log, m_numPatchesToDraw, result.numPrimitives, result.refNumPrimitives, patchTessLevels); 688abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.success = false; 689abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 690abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 691abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 692abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 693abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid BaseTestInstance::uploadVertexAttributes (const std::vector<float>& vertexData) 694abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 695abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DeviceInterface& vk = m_context.getDeviceInterface(); 696abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDevice device = m_context.getDevice(); 697abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 698abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = m_vertexBuffer.getAllocation(); 699abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemcpy(alloc.getHostPtr(), &vertexData[0], sizeInBytes(vertexData)); 700abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeInBytes(vertexData)); 701abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 702abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 703abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 704abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #2 705abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 706abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the set of vertices along an outer edge of a quad or triangle 707abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * only depends on that edge's tessellation level, and spacing. 708abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 709abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * For each (outer) edge in the quad or triangle, draw multiple patches 710abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * with identical tessellation levels for that outer edge but with 711abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * different values for the other outer edges; compare, among the 712abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * primitives, the vertices generated for that outer edge. Repeat with 713abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * different programs, using different winding etc. settings. Compare 714abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * the edge's vertices between different programs. 715abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 716abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass OuterEdgeDivisionTestInstance : public BaseTestInstance 717abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 718abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 719abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDivisionTestInstance (Context& context, const CaseDefinition caseDef) : BaseTestInstance (context, caseDef, 10) {} 720abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestStatus iterate (void); 721abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 722abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 723abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus OuterEdgeDivisionTestInstance::iterate (void) 724abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 725abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeIndex = 0; outerEdgeIndex < static_cast<int>(m_edgeDescriptions.size()); ++outerEdgeIndex) 726abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(m_singleOuterEdgeLevels); ++outerEdgeLevelCaseNdx) 727abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 728abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const OuterEdgeDescription& edgeDesc = m_edgeDescriptions[outerEdgeIndex]; 729abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<float> patchTessLevels = generatePatchTessLevels(m_numPatchesToDraw, outerEdgeIndex, m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 730abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 731abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set firstOuterEdgeVertices; // Vertices of the outer edge of the first patch of the first program's draw call; used for comparison with other patches. 732abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 733abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski uploadVertexAttributes(patchTessLevels); 734abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski logOuterTessellationLevel(m_context.getTestContext().getLog(), m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx], edgeDesc); 735abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 736abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int windingNdx = 0; windingNdx < WINDING_LAST; ++windingNdx) 737abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int usePointModeNdx = 0; usePointModeNdx <= 1; ++usePointModeNdx) 738abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 739abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Winding winding = static_cast<Winding>(windingNdx); 740abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool usePointMode = (usePointModeNdx != 0); 741abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool isFirstProgram = (windingNdx == 0 && usePointModeNdx == 0); 742abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 743abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DrawResult result = draw(static_cast<deUint32>(patchTessLevels.size()), patchTessLevels, winding, usePointMode); 744abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 745abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!result.success) 746abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 747abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 748abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Check the vertices of each patch. 749abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 750abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int primitiveNdx = 0; 751abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int patchNdx = 0; patchNdx < m_numPatchesToDraw; ++patchNdx) 752abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 753abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(primitiveNdx < result.numPrimitives); 754abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 755abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const float* const innerLevels = &patchTessLevels[NUM_TESS_LEVELS*patchNdx + 0]; 756abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const float* const outerLevels = &patchTessLevels[NUM_TESS_LEVELS*patchNdx + 2]; 757abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 758abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set outerEdgeVertices; 759abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 760abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // We're interested in just the vertices on the current outer edge. 761abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (; primitiveNdx < result.numPrimitives && result.primitives[primitiveNdx].patchPrimitiveID == patchNdx; ++primitiveNdx) 762abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < result.numPrimitiveVertices; ++i) 763abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 764abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& coord = result.primitives[primitiveNdx].tessCoord[i].swizzle(0, 1, 2); 765abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (edgeDesc.contains(coord)) 766abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeVertices.insert(coord); 767abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 768abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 769abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Compare the vertices to those of the first patch (unless this is the first patch). 770abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 771abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (isFirstProgram && patchNdx == 0) 772abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski firstOuterEdgeVertices = outerEdgeVertices; 773abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (firstOuterEdgeVertices != outerEdgeVertices) 774abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 775abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = m_context.getTestContext().getLog(); 776abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 777abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 778abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Failure: vertices generated for the edge differ between the following cases:\n" 779abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case A: " << getProgramDescription((Winding)0, (bool)0) << ", tessellation levels: " 780abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getTessellationLevelsString(&patchTessLevels[0], &patchTessLevels[2]) << "\n" 781abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case B: " << getProgramDescription(winding, usePointMode) << ", tessellation levels: " 782abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getTessellationLevelsString(innerLevels, outerLevels) 783abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 784abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 785abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 786abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Note: resulting vertices for the edge for the cases were:\n" 787abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case A: " << containerStr(firstOuterEdgeVertices, 5, 14) << "\n" 788abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case B: " << containerStr(outerEdgeVertices, 5, 14) 789abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 790abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 791abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 792abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 793abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 794abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(primitiveNdx == result.numPrimitives); 795abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } // for windingNdx, usePointModeNdx 796abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } // for outerEdgeIndex, outerEdgeLevelCaseNdx 797abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 798abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::pass("OK"); 799abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 800abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 801abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 802abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #4 803abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 804abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the vertices on an outer edge don't depend on which of the 805abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * edges it is, other than with respect to component order. 806abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 807abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass OuterEdgeIndexIndependenceTestInstance : public BaseTestInstance 808abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 809abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 810abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeIndexIndependenceTestInstance (Context& context, const CaseDefinition caseDef) : BaseTestInstance (context, caseDef, 1) {} 811abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestStatus iterate (void); 812abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 813abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 814abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus OuterEdgeIndexIndependenceTestInstance::iterate (void) 815abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 816abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(m_singleOuterEdgeLevels); ++outerEdgeLevelCaseNdx) 817abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 818abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set firstEdgeVertices; 819abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 820abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeIndex = 0; outerEdgeIndex < static_cast<int>(m_edgeDescriptions.size()); ++outerEdgeIndex) 821abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 822abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const OuterEdgeDescription& edgeDesc = m_edgeDescriptions[outerEdgeIndex]; 823abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<float> patchTessLevels = generatePatchTessLevels(m_numPatchesToDraw, outerEdgeIndex, m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 824abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 825abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski uploadVertexAttributes(patchTessLevels); 826abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski logOuterTessellationLevel(m_context.getTestContext().getLog(), m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx], edgeDesc); 827abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DrawResult result = draw(static_cast<deUint32>(patchTessLevels.size()), patchTessLevels, m_caseDef.winding, m_caseDef.usePointMode); 828abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 829abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Verify case result 830abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 831abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!result.success) 832abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 833abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 834abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set currentEdgeVertices; 835abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 836abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Get the vertices on the current outer edge. 837abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int primitiveNdx = 0; primitiveNdx < result.numPrimitives; ++primitiveNdx) 838abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < result.numPrimitiveVertices; ++i) 839abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 840abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& coord = result.primitives[primitiveNdx].tessCoord[i].swizzle(0, 1, 2); 841abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (edgeDesc.contains(coord)) 842abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 843abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Swizzle components to match the order of the first edge. 844abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 845abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski currentEdgeVertices.insert(outerEdgeIndex == 0 ? coord : 846abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 1 ? coord.swizzle(1, 0, 2) : 847abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 2 ? coord.swizzle(2, 1, 0) : tcu::Vec3(-1.0f)); 848abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) 849abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski currentEdgeVertices.insert(tcu::Vec3(outerEdgeIndex == 0 ? coord.y() : 850abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 1 ? coord.x() : 851abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 2 ? coord.y() : 852abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 3 ? coord.x() : -1.0f, 853abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 0.0f, 0.0f)); 854abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 855abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 856abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 857abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 858abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 859abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (outerEdgeIndex == 0) 860abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski firstEdgeVertices = currentEdgeVertices; 861abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 862abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 863abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Compare vertices of this edge to those of the first edge. 864abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (currentEdgeVertices != firstEdgeVertices) 865abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 866abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const char* const swizzleDesc = 867abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? (outerEdgeIndex == 1 ? "(y, x, z)" : 868abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 2 ? "(z, y, x)" : DE_NULL) : 869abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ? (outerEdgeIndex == 1 ? "(x, 0)" : 870abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 2 ? "(y, 0)" : 871abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeIndex == 3 ? "(x, 0)" : DE_NULL) 872abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : DE_NULL; 873abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 874abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = m_context.getTestContext().getLog(); 875abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 876abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Failure: the set of vertices on the " << edgeDesc.description() << " edge" 877abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " doesn't match the set of vertices on the " << m_edgeDescriptions[0].description() << " edge" 878abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 879abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 880abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 881abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Note: set of vertices on " << edgeDesc.description() << " edge, components swizzled like " << swizzleDesc 882abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " to match component order on first edge:\n" << containerStr(currentEdgeVertices, 5) 883abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\non " << m_edgeDescriptions[0].description() << " edge:\n" << containerStr(firstEdgeVertices, 5) 884abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 885abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 886abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 887abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 888abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 889abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 890abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 891abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::pass("OK"); 892abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 893abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 894abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 895abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #3 896abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 897abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the vertices along an outer edge are placed symmetrically. 898abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 899abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Draw multiple patches with different tessellation levels and different 900abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * point_mode, winding etc. Before outputting tesscoords from shader, mirror 901abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * the vertices in the TES such that every vertex on an outer edge - 902abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * except the possible middle vertex - should be duplicated in the output. 903abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Check that appropriate duplicates exist. 904abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 905abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass SymmetricOuterEdgeTestInstance : public BaseTestInstance 906abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 907abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 908abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski SymmetricOuterEdgeTestInstance (Context& context, const CaseDefinition caseDef) : BaseTestInstance (context, caseDef, 1) {} 909abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestStatus iterate (void); 910abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 911abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 912abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus SymmetricOuterEdgeTestInstance::iterate (void) 913abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 914abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeIndex = 0; outerEdgeIndex < static_cast<int>(m_edgeDescriptions.size()); ++outerEdgeIndex) 915abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int outerEdgeLevelCaseNdx = 0; outerEdgeLevelCaseNdx < DE_LENGTH_OF_ARRAY(m_singleOuterEdgeLevels); ++outerEdgeLevelCaseNdx) 916abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 917abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const OuterEdgeDescription& edgeDesc = m_edgeDescriptions[outerEdgeIndex]; 918abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<float> patchTessLevels = generatePatchTessLevels(m_numPatchesToDraw, outerEdgeIndex, m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx]); 919abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 920abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski uploadVertexAttributes(patchTessLevels); 921abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski logOuterTessellationLevel(m_context.getTestContext().getLog(), m_singleOuterEdgeLevels[outerEdgeLevelCaseNdx], edgeDesc); 922abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DrawResult result = draw(static_cast<deUint32>(patchTessLevels.size()), patchTessLevels, m_caseDef.winding, m_caseDef.usePointMode); 923abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 924abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Verify case result 925abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 926abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!result.success) 927abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 928abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 929abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set nonMirroredEdgeVertices; 930abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Vec3Set mirroredEdgeVertices; 931abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 932abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Get the vertices on the current outer edge. 933abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int primitiveNdx = 0; primitiveNdx < result.numPrimitives; ++primitiveNdx) 934abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < result.numPrimitiveVertices; ++i) 935abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 936abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& coord = result.primitives[primitiveNdx].tessCoord[i].swizzle(0, 1, 2); 937abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (edgeDesc.contains(coord)) 938abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 939abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Ignore the middle vertex of the outer edge, as it's exactly at the mirroring point; 940abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // for isolines, also ignore (0, 0) and (1, 0) because there's no mirrored counterpart for them. 941abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES && 942abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski coord == tcu::select(tcu::Vec3(0.0f), tcu::Vec3(0.5f), singleTrueMask<3>(edgeDesc.constantCoordinateIndex))) 943abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski continue; 944abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS && 945abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski coord.swizzle(0,1) == tcu::select(tcu::Vec2(edgeDesc.constantCoordinateValueChoices[0]), tcu::Vec2(0.5f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex))) 946abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski continue; 947abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_ISOLINES && 948abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski (coord == tcu::Vec3(0.0f, 0.5f, 0.0f) || coord == tcu::Vec3(1.0f, 0.5f, 0.0f) || coord == tcu::Vec3(0.0f, 0.0f, 0.0f) || coord == tcu::Vec3(1.0f, 0.0f, 0.0f))) 949abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski continue; 950abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 951abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool isMirrored = result.primitives[primitiveNdx].tessCoord[i].w() > 0.5f; 952abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (isMirrored) 953abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski mirroredEdgeVertices.insert(coord); 954abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 955abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski nonMirroredEdgeVertices.insert(coord); 956abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 957abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 958abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 959abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType != TESSPRIMITIVETYPE_ISOLINES) 960abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 961abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Check that both endpoints are present. Note that endpoints aren't mirrored by the shader, since they belong to more than one edge. 962abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 963abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::Vec3 endpointA; 964abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::Vec3 endpointB; 965abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 966abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 967abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 968abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endpointA = tcu::select(tcu::Vec3(1.0f), tcu::Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 1) % 3)); 969abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endpointB = tcu::select(tcu::Vec3(1.0f), tcu::Vec3(0.0f), singleTrueMask<3>((edgeDesc.constantCoordinateIndex + 2) % 3)); 970abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 971abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) 972abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 973abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endpointA.xy() = tcu::select(tcu::Vec2(edgeDesc.constantCoordinateValueChoices[0]), tcu::Vec2(0.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex)); 974abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endpointB.xy() = tcu::select(tcu::Vec2(edgeDesc.constantCoordinateValueChoices[0]), tcu::Vec2(1.0f), singleTrueMask<2>(edgeDesc.constantCoordinateIndex)); 975abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 976abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 977abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 978abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 979abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!contains(nonMirroredEdgeVertices, endpointA) || 980abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski !contains(nonMirroredEdgeVertices, endpointB)) 981abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 982abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski m_context.getTestContext().getLog() 983abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Failure: edge doesn't contain both endpoints, " << endpointA << " and " << endpointB << tcu::TestLog::EndMessage 984abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5) 985abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << tcu::TestLog::EndMessage; 986abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 987abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 988abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 989abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski nonMirroredEdgeVertices.erase(endpointA); 990abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski nonMirroredEdgeVertices.erase(endpointB); 991abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 992abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 993abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (nonMirroredEdgeVertices != mirroredEdgeVertices) 994abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 995abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski m_context.getTestContext().getLog() 996abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Failure: the set of mirrored edges isn't equal to the set of non-mirrored edges (ignoring endpoints and possible middle)" << tcu::TestLog::EndMessage 997abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Note: non-mirrored vertices:\n" << containerStr(nonMirroredEdgeVertices, 5) 998abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\nmirrored vertices:\n" << containerStr(mirroredEdgeVertices, 5) << tcu::TestLog::EndMessage; 999abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1000abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of vertices"); 1001abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1002abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1003abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::pass("OK"); 1004abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1005abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1006abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass OuterEdgeDivisionTest : public TestCase 1007abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1008abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1009abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeDivisionTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const CaseDefinition caseDef) 1010abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : TestCase (testCtx, name, description) 1011abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_caseDef (caseDef) 1012abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1013abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1014abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1015abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski void initPrograms (vk::SourceCollections& programCollection) const 1016abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1017abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski addDefaultPrograms(programCollection, m_caseDef.primitiveType, m_caseDef.spacingMode, WINDING_USAGE_VARY, POINT_MODE_USAGE_VARY); 1018abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1019abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1020abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TestInstance* createInstance (Context& context) const 1021abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1022abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new OuterEdgeDivisionTestInstance(context, m_caseDef); 1023abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1024abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1025abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate: 1026abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 1027abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1028abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1029abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass OuterEdgeIndexIndependenceTest : public TestCase 1030abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1031abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1032abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski OuterEdgeIndexIndependenceTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const CaseDefinition caseDef) 1033abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : TestCase (testCtx, name, description) 1034abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_caseDef (caseDef) 1035abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1036abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES || m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS); 1037abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1038abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1039abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski void initPrograms (vk::SourceCollections& programCollection) const 1040abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1041abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski addDefaultPrograms(programCollection, m_caseDef.primitiveType, m_caseDef.spacingMode, getWindingUsage(m_caseDef.winding), getPointModeUsage(m_caseDef.usePointMode)); 1042abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1043abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1044abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TestInstance* createInstance (Context& context) const 1045abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1046abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new OuterEdgeIndexIndependenceTestInstance(context, m_caseDef); 1047abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1048abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1049abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate: 1050abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 1051abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1052abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1053abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass SymmetricOuterEdgeTest : public TestCase 1054abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1055abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1056abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski SymmetricOuterEdgeTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const CaseDefinition caseDef) 1057abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : TestCase (testCtx, name, description) 1058abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_caseDef (caseDef) 1059abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1060abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1061abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1062abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski void initPrograms (vk::SourceCollections& programCollection) const 1063abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1064abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool mirrorCoords = true; 1065abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski addDefaultPrograms(programCollection, m_caseDef.primitiveType, m_caseDef.spacingMode, getWindingUsage(m_caseDef.winding), getPointModeUsage(m_caseDef.usePointMode), mirrorCoords); 1066abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1067abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1068abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TestInstance* createInstance (Context& context) const 1069abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1070abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new SymmetricOuterEdgeTestInstance(context, m_caseDef); 1071abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1072abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1073abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate: 1074abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 1075abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1076abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1077abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCase* makeOuterEdgeDivisionTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode) 1078abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1079abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { primitiveType, spacingMode, WINDING_LAST, false }; // winding is ignored by this test 1080abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new OuterEdgeDivisionTest(testCtx, name, description, caseDef); 1081abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1082abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1083abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCase* makeOuterEdgeIndexIndependenceTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const Winding winding, const bool usePointMode) 1084abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1085abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { primitiveType, spacingMode, winding, usePointMode }; 1086abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new OuterEdgeIndexIndependenceTest(testCtx, name, description, caseDef); 1087abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1088abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1089abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCase* makeSymmetricOuterEdgeTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const Winding winding, const bool usePointMode) 1090abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1091abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { primitiveType, spacingMode, winding, usePointMode }; 1092abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new SymmetricOuterEdgeTest(testCtx, name, description, caseDef); 1093abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1094abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1095abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // InvariantOuterEdge ns 1096abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1097abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace PrimitiveSetInvariance 1098abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1099abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskienum CaseType 1101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_INVARIANT_PRIMITIVE_SET, 1103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_INVARIANT_TRIANGLE_SET, 1104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_INVARIANT_OUTER_TRIANGLE_SET, 1105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_INVARIANT_INNER_TRIANGLE_SET, 1106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct CaseDefinition 1109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CaseType caseType; 1111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessPrimitiveType primitiveType; 1112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski SpacingMode spacingMode; 1113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski WindingUsage windingUsage; 1114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool usePointMode; 1115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct LevelCase 1118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<TessLevels> levels; 1120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int mem; //!< Subclass-defined arbitrary piece of data, for type of the levelcase, if needed. 1121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski LevelCase (const TessLevels& lev) : levels(std::vector<TessLevels>(1, lev)), mem(0) {} 1123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski LevelCase (void) : mem(0) {} 1124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitypedef tcu::Vector<tcu::Vec3, 3> Triangle; 1127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiinline Triangle makeTriangle (const PerPrimitive& primitive) 1129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return Triangle(primitive.tessCoord[0].swizzle(0, 1, 2), 1131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski primitive.tessCoord[1].swizzle(0, 1, 2), 1132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski primitive.tessCoord[2].swizzle(0, 1, 2)); 1133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Compare triangle sets, ignoring triangle order and vertex order within triangle, and possibly exclude some triangles too. 1136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename IsTriangleRelevantT> 1137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool compareTriangleSets (const PerPrimitiveVec& primitivesA, 1138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PerPrimitiveVec& primitivesB, 1139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log, 1140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const IsTriangleRelevantT& isTriangleRelevant, 1141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const char* ignoredTriangleDescription = DE_NULL) 1142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski typedef LexCompare<Triangle, 3, VecLexLessThan<3> > TriangleLexLessThan; 1144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski typedef std::set<Triangle, TriangleLexLessThan> TriangleSet; 1145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numTrianglesA = static_cast<int>(primitivesA.size()); 1147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numTrianglesB = static_cast<int>(primitivesB.size()); 1148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TriangleSet trianglesA; 1149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TriangleSet trianglesB; 1150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int aOrB = 0; aOrB < 2; ++aOrB) 1152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PerPrimitiveVec& primitives = aOrB == 0 ? primitivesA : primitivesB; 1154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numTriangles = aOrB == 0 ? numTrianglesA : numTrianglesB; 1155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TriangleSet& triangles = aOrB == 0 ? trianglesA : trianglesB; 1156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int triNdx = 0; triNdx < numTriangles; ++triNdx) 1158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Triangle triangle = makeTriangle(primitives[triNdx]); 1160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (isTriangleRelevant(triangle.getPtr())) 1162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::sort(triangle.getPtr(), triangle.getPtr()+3, VecLexLessThan<3>()); 1164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski triangles.insert(triangle); 1165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TriangleSet::const_iterator aIt = trianglesA.begin(); 1170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TriangleSet::const_iterator bIt = trianglesB.begin(); 1171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski while (aIt != trianglesA.end() || bIt != trianglesB.end()) 1173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool aEnd = aIt == trianglesA.end(); 1175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool bEnd = bIt == trianglesB.end(); 1176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (aEnd || bEnd || *aIt != *bIt) 1178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Failure: triangle sets in two cases are not equal (when ignoring triangle and vertex order" 1180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << (ignoredTriangleDescription == DE_NULL ? "" : std::string() + ", and " + ignoredTriangleDescription) << ")" << tcu::TestLog::EndMessage; 1181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!aEnd && (bEnd || TriangleLexLessThan()(*aIt, *bIt))) 1183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Note: e.g. triangle " << *aIt << " exists for first case but not for second" << tcu::TestLog::EndMessage; 1184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 1185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Note: e.g. triangle " << *bIt << " exists for second case but not for first" << tcu::TestLog::EndMessage; 1186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ++aIt; 1191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ++bIt; 1192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitemplate <typename ArgT, bool res> 1199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct ConstantUnaryPredicate 1200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const ArgT&) const { return res; } 1202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool compareTriangleSets (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, tcu::TestLog& log) 1205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1206abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, log, ConstantUnaryPredicate<const tcu::Vec3*, true>()); 1207abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1208abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1209abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Compare two sets of primitives. Order of primitives in each set is undefined, but within each primitive 1210abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! vertex order and coordinates are expected to match exactly. 1211abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool comparePrimitivesExact (const PerPrimitive* const primitivesA, const PerPrimitive* const primitivesB, const int numPrimitivesPerPatch) 1212abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1213abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int ndxB = 0; 1214abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int ndxA = 0; ndxA < numPrimitivesPerPatch; ++ndxA) 1215abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1216abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec4 (&coordsA)[3] = primitivesA[ndxA].tessCoord; 1217abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool match = false; 1218abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1219abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Actually both sets are usually somewhat sorted, so don't reset ndxB after each match. Instead, continue from the next index. 1220abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numPrimitivesPerPatch; ++i) 1221abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1222abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec4 (&coordsB)[3] = primitivesB[ndxB].tessCoord; 1223abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ndxB = (ndxB + 1) % numPrimitivesPerPatch; 1224abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1225abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (coordsA[0] == coordsB[0] && coordsA[1] == coordsB[1] && coordsA[2] == coordsB[2]) 1226abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1227abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski match = true; 1228abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski break; 1229abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1230abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1231abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1232abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!match) 1233abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1234abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1235abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1236abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1237abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1238abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 1239abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Base class for testing invariance of entire primitive set 1240abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1241abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Draws two patches with identical tessellation levels and compares the 1242abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * results. Repeats the same with other programs that are only different 1243abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * in irrelevant ways; compares the results between these two programs. 1244abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Also potentially compares to results produced by different tessellation 1245abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * levels (see e.g. invariance rule #6). 1246abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Furthermore, repeats the above with multiple different tessellation 1247abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * value sets. 1248abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1249abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * The manner of primitive set comparison is defined by subclass. E.g. 1250abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * case for invariance rule #1 tests that same vertices come out, in same 1251abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * order; rule #5 only requires that the same triangles are output, but 1252abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * not necessarily in the same order. 1253abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 1254abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvarianceTestCase : public TestCase 1255abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1256abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1257abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvarianceTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, const CaseDefinition& caseDef) 1258abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : TestCase (context, name, description) 1259abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski , m_caseDef (caseDef) {} 1260abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1261abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski virtual ~InvarianceTestCase (void) {} 1262abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1263abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski void initPrograms (SourceCollections& programCollection) const; 1264abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TestInstance* createInstance (Context& context) const; 1265abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1266abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprivate: 1267abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 1268abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1269abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1270abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid InvarianceTestCase::initPrograms (SourceCollections& programCollection) const 1271abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1272abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski addDefaultPrograms(programCollection, m_caseDef.primitiveType, m_caseDef.spacingMode, m_caseDef.windingUsage, getPointModeUsage(m_caseDef.usePointMode)); 1273abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1274abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1275abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvarianceTestInstance : public TestInstance 1276abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1277abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1278abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvarianceTestInstance (Context& context, const CaseDefinition& caseDef) : TestInstance(context), m_caseDef(caseDef) {} 1279abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski virtual ~InvarianceTestInstance (void) {} 1280abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1281abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestStatus iterate (void); 1282abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1283abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 1284abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski virtual std::vector<LevelCase> genTessLevelCases (void) const; 1285abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski virtual bool compare (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, const int levelCaseMem) const = 0; 1286abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1287abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition m_caseDef; 1288abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1289abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1290abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<LevelCase> InvarianceTestInstance::genTessLevelCases (void) const 1291abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1292abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static const TessLevels basicTessLevelCases[] = 1293abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1294abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 1295abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 63.0f, 24.0f }, { 15.0f, 42.0f, 10.0f, 12.0f } }, 1296abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 3.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 1297abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 4.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 1298abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 2.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, 1299abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 5.0f, 6.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, 1300abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 1.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 1301abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 5.0f, 1.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, 1302abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { { 5.2f, 1.6f }, { 2.9f, 3.4f, 1.5f, 4.1f } } 1303abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1304abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1305abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<LevelCase> result; 1306abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < DE_LENGTH_OF_ARRAY(basicTessLevelCases); ++i) 1307abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.push_back(LevelCase(basicTessLevelCases[i])); 1308abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1309abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1310abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::Random rnd(123); 1311abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < 10; ++i) 1312abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1313abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessLevels levels; 1314abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.inner); ++j) 1315abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.inner[j] = rnd.getFloat(1.0f, 16.0f); 1316abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int j = 0; j < DE_LENGTH_OF_ARRAY(levels.outer); ++j) 1317abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[j] = rnd.getFloat(1.0f, 16.0f); 1318abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.push_back(LevelCase(levels)); 1319abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1320abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1321abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1322abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 1323abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1324abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1325abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus InvarianceTestInstance::iterate (void) 1326abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1327abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski requireFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), 1328abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski FEATURE_TESSELLATION_SHADER | FEATURE_GEOMETRY_SHADER | FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 1329abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1330abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DeviceInterface& vk = m_context.getDeviceInterface(); 1331abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDevice device = m_context.getDevice(); 1332abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkQueue queue = m_context.getUniversalQueue(); 1333abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 1334abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Allocator& allocator = m_context.getDefaultAllocator(); 1335abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1336abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<LevelCase> tessLevelCases = genTessLevelCases(); 1337abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numPatchesPerDrawCall = 2; 1338abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int maxNumPrimitivesPerPatch = 0; // computed below 1339abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<std::vector<int> > primitiveCounts; 1340abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1341abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int caseNdx = 0; caseNdx < static_cast<int>(tessLevelCases.size()); ++caseNdx) 1342abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1343abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski primitiveCounts.push_back(std::vector<int>()); 1344abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int levelNdx = 0; levelNdx < static_cast<int>(tessLevelCases[caseNdx].levels.size()); ++levelNdx) 1345abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1346abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int primitiveCount = referencePrimitiveCount(m_caseDef.primitiveType, m_caseDef.spacingMode, m_caseDef.usePointMode, 1347abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski &tessLevelCases[caseNdx].levels[levelNdx].inner[0], &tessLevelCases[caseNdx].levels[levelNdx].outer[0]); 1348abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski primitiveCounts.back().push_back(primitiveCount); 1349abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski maxNumPrimitivesPerPatch = de::max(maxNumPrimitivesPerPatch, primitiveCount); 1350abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1351abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1352abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1353abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Vertex input attributes buffer: to pass tessellation levels 1354abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1355abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkFormat vertexFormat = VK_FORMAT_R32_SFLOAT; 1356abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deUint32 vertexStride = tcu::getPixelSize(mapVkFormat(vertexFormat)); 1357abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize vertexDataSizeBytes = NUM_TESS_LEVELS * numPatchesPerDrawCall * vertexStride; 1358abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer vertexBuffer (vk, device, allocator, makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible); 1359abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1360abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Output buffer: number of primitives and an array of PerPrimitive structures 1361abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1362abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int resultBufferMaxVertices = numPatchesPerDrawCall * maxNumPrimitivesPerPatch * numVerticesPerPrimitive(m_caseDef.primitiveType, m_caseDef.usePointMode); 13636e5ef4c51158771e71f72c70980b4dbd78f011f2Pyry Haulos const int resultBufferTessCoordsOffset = (int)sizeof(deInt32) * 4; 1364abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize resultBufferSizeBytes = resultBufferTessCoordsOffset + resultBufferMaxVertices * sizeof(PerPrimitive); 1365abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer resultBuffer (vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); 1366abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1367abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Descriptors 1368abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1369abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder() 1370abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT) 1371abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(vk, device)); 1372abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1373abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder() 1374abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 1375abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 1376abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1377abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); 1378abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes); 1379abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1380abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DescriptorSetUpdateBuilder() 1381abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo) 1382abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .update(vk, device); 1383abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1384abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkRenderPass> renderPass (makeRenderPassWithoutAttachments (vk, device)); 1385abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkFramebuffer> framebuffer (makeFramebufferWithoutAttachments(vk, device, *renderPass)); 1386abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout (vk, device, *descriptorSetLayout)); 1387abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkCommandPool> cmdPool (makeCommandPool (vk, device, queueFamilyIndex)); 138855dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 1389abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1390abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < static_cast<int>(tessLevelCases.size()); ++tessLevelCaseNdx) 1391abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1392abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const LevelCase& levelCase = tessLevelCases[tessLevelCaseNdx]; 1393abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski PerPrimitiveVec firstPrim; 1394abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1395abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1396abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = m_context.getTestContext().getLog(); 1397abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream tessLevelsStr; 1398abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1399abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < static_cast<int>(levelCase.levels.size()); ++i) 1400abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessLevelsStr << (levelCase.levels.size() > 1u ? "\n" : "") << getTessellationLevelsString(levelCase.levels[i], m_caseDef.primitiveType); 1401abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1402abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Tessellation level sets: " << tessLevelsStr.str() << tcu::TestLog::EndMessage; 1403abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1404abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1405abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int subTessLevelCaseNdx = 0; subTessLevelCaseNdx < static_cast<int>(levelCase.levels.size()); ++subTessLevelCaseNdx) 1406abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1407abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const TessLevels& tessLevels = levelCase.levels[subTessLevelCaseNdx]; 1408abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1409abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessLevels data[2]; 1410abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski data[0] = tessLevels; 1411abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski data[1] = tessLevels; 1412abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1413abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = vertexBuffer.getAllocation(); 1414abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemcpy(alloc.getHostPtr(), data, sizeof(data)); 1415abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(data)); 1416abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1417abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1418abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int programNdx = 0; 1419abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<Winding> windingCases = getWindingCases(m_caseDef.windingUsage); 1420abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (std::vector<Winding>::const_iterator windingIter = windingCases.begin(); windingIter != windingCases.end(); ++windingIter) 1421abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1422abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkPipeline> pipeline(GraphicsPipelineBuilder() 1423abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setPatchControlPoints (NUM_TESS_LEVELS) 1424abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setVertexInputSingleAttribute(vertexFormat, vertexStride) 1425abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert"), DE_NULL) 1426abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_context.getBinaryCollection().get("tesc"), DE_NULL) 1427abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get(getProgramName("tese", *windingIter, m_caseDef.usePointMode)), DE_NULL) 1428abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_GEOMETRY_BIT, m_context.getBinaryCollection().get(getProgramName("geom", m_caseDef.usePointMode)), DE_NULL) 1429abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build (vk, device, *pipelineLayout, *renderPass)); 1430abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1431abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1432abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = resultBuffer.getAllocation(); 1433abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(resultBufferSizeBytes)); 1434abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes); 1435abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1436abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1437abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginCommandBuffer(vk, *cmdBuffer); 1438abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginRenderPassWithRasterizationDisabled(vk, *cmdBuffer, *renderPass, *framebuffer); 1439abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1440abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 1441abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 1442abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1443abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize vertexBufferOffset = 0ull; 1444abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 1445abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1446abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1447abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdDraw(*cmdBuffer, numPatchesPerDrawCall * NUM_TESS_LEVELS, 1u, 0u, 0u); 1448abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endRenderPass(vk, *cmdBuffer); 1449abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1450abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1451abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( 1452abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes); 1453abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1454abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1455abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL); 1456abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1457abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1458abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endCommandBuffer(vk, *cmdBuffer); 1459abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1460abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1461abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Verify case result 1462abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1463abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& resultAlloc = resultBuffer.getAllocation(); 1464abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), resultBufferSizeBytes); 1465abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1466abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int refNumPrimitives = numPatchesPerDrawCall * primitiveCounts[tessLevelCaseNdx][subTessLevelCaseNdx]; 1467abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numPrimitiveVertices = numVerticesPerPrimitive(m_caseDef.primitiveType, m_caseDef.usePointMode); 1468abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deInt32 numPrimitives = *static_cast<deInt32*>(resultAlloc.getHostPtr()); 1469abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PerPrimitiveVec primitives = sorted(readInterleavedData<PerPrimitive>(numPrimitives, resultAlloc.getHostPtr(), resultBufferTessCoordsOffset, sizeof(PerPrimitive)), 1470abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski byPatchPrimitiveID); 1471abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1472abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // If this fails then we didn't read all vertices from shader and test must be changed to allow more. 1473abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(numPrimitiveVertices * numPrimitives <= resultBufferMaxVertices); 1474079a481256d63e8498f7adf38a234bfe74bb04dePyry Haulos DE_UNREF(numPrimitiveVertices); 1475abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1476abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = m_context.getTestContext().getLog(); 1477abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1478abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (numPrimitives != refNumPrimitives) 1479abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1480abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Failure: got " << numPrimitives << " primitives, but expected " << refNumPrimitives << tcu::TestLog::EndMessage; 1481abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1482abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of primitives"); 1483abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1484abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1485abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int half = static_cast<int>(primitives.size() / 2); 1486abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PerPrimitiveVec prim0 = PerPrimitiveVec(primitives.begin(), primitives.begin() + half); 1487abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const PerPrimitive* const prim1 = &primitives[half]; 1488abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1489abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!comparePrimitivesExact(&prim0[0], prim1, half)) 1490abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1491abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Failure: tessellation coordinates differ between two primitives drawn in one draw call" << tcu::TestLog::EndMessage 1492abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Note: tessellation levels for both primitives were: " << getTessellationLevelsString(tessLevels, m_caseDef.primitiveType) << tcu::TestLog::EndMessage; 1493abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1494abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of primitives"); 1495abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1496abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1497abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (programNdx == 0 && subTessLevelCaseNdx == 0) 1498abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski firstPrim = prim0; 1499abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 1500abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1501abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool compareOk = compare(firstPrim, prim0, levelCase.mem); 1502abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!compareOk) 1503abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1504abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message 1505abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Note: comparison of tessellation coordinates failed; comparison was made between following cases:\n" 1506abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case A: program 0, tessellation levels: " << getTessellationLevelsString(tessLevelCases[tessLevelCaseNdx].levels[0], m_caseDef.primitiveType) << "\n" 1507abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " - case B: program " << programNdx << ", tessellation levels: " << getTessellationLevelsString(tessLevels, m_caseDef.primitiveType) 1508abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 1509abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1510abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::fail("Invalid set of primitives"); 1511abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1512abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1513abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1514abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ++programNdx; 1515abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1516abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1517abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1518abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::pass("OK"); 1519abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1520abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1521abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 1522abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #1 1523abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1524abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the sequence of primitives input to the TES only depends on 1525abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * the tessellation levels, tessellation mode, spacing mode, winding, and 1526abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * point mode. 1527abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 1528abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvariantPrimitiveSetTestInstance : public InvarianceTestInstance 1529abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1530abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1531abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvariantPrimitiveSetTestInstance (Context& context, const CaseDefinition& caseDef) : InvarianceTestInstance(context, caseDef) {} 1532abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1533abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 1534abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool compare (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, const int) const 1535abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1536abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!comparePrimitivesExact(&primitivesA[0], &primitivesB[0], static_cast<int>(primitivesA.size()))) 1537abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1538abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski m_context.getTestContext().getLog() 1539abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message << "Failure: tessellation coordinates differ between two programs" << tcu::TestLog::EndMessage; 1540abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1541abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1542abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1543abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1544abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1545abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1546abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1547abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 1548abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #5 1549abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1550abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the set of triangles input to the TES only depends on the 1551abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * tessellation levels, tessellation mode and spacing mode. Specifically, 1552abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * winding doesn't change the set of triangles, though it can change the 1553abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * order in which they are input to TES, and can (and will) change the 1554abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * vertex order within a triangle. 1555abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 1556abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvariantTriangleSetTestInstance : public InvarianceTestInstance 1557abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1558abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1559abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvariantTriangleSetTestInstance (Context& context, const CaseDefinition& caseDef) : InvarianceTestInstance(context, caseDef) {} 1560abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1561abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 1562abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool compare (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, const int) const 1563abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1564abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, m_context.getTestContext().getLog()); 1565abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1566abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1567abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1568abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 1569abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #6 1570abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1571abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the set of inner triangles input to the TES only depends on 1572abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * the inner tessellation levels, tessellation mode and spacing mode. 1573abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 1574abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvariantInnerTriangleSetTestInstance : public InvarianceTestInstance 1575abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1576abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1577abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvariantInnerTriangleSetTestInstance (Context& context, const CaseDefinition& caseDef) : InvarianceTestInstance(context, caseDef) {} 1578abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1579abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 1580abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<LevelCase> genTessLevelCases (void) const 1581abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1582abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numSubCases = 4; 1583abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<LevelCase> baseResults = InvarianceTestInstance::genTessLevelCases(); 1584abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<LevelCase> result; 1585abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::Random rnd (123); 1586abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1587abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Generate variants with different values for irrelevant levels. 1588abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int baseNdx = 0; baseNdx < static_cast<int>(baseResults.size()); ++baseNdx) 1589abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1590abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const TessLevels& base = baseResults[baseNdx].levels[0]; 1591abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessLevels levels = base; 1592abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski LevelCase levelCase; 1593abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1594abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int subNdx = 0; subNdx < numSubCases; ++subNdx) 1595abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1596abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levelCase.levels.push_back(levels); 1597abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1598abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); ++i) 1599abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[i] = rnd.getFloat(2.0f, 16.0f); 1600abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 1601abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.inner[1] = rnd.getFloat(2.0f, 16.0f); 1602abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1603abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1604abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.push_back(levelCase); 1605abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1606abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1607abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 1608abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1609abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1610abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski struct IsInnerTriangleTriangle 1611abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1612abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const tcu::Vec3* vertices) const 1613abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1614abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int v = 0; v < 3; ++v) 1615abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int c = 0; c < 3; ++c) 1616abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (vertices[v][c] == 0.0f) 1617abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1618abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1619abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1620abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1621abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1622abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski struct IsInnerQuadTriangle 1623abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1624abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const tcu::Vec3* vertices) const 1625abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1626abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int v = 0; v < 3; ++v) 1627abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int c = 0; c < 2; ++c) 1628abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (vertices[v][c] == 0.0f || vertices[v][c] == 1.0f) 1629abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1630abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1631abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1632abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1633abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1634abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool compare (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, const int) const 1635abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1636abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 1637abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, m_context.getTestContext().getLog(), IsInnerTriangleTriangle(), "outer triangles"); 1638abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) 1639abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, m_context.getTestContext().getLog(), IsInnerQuadTriangle(), "outer triangles"); 1640abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 1641abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1642abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 1643abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1644abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1645abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1646abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1647abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1648abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski/*--------------------------------------------------------------------*//*! 1649abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * \brief Test invariance rule #7 1650abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * 1651abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * Test that the set of outer triangles input to the TES only depends on 1652abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * tessellation mode, spacing mode and the inner and outer tessellation 1653abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * levels corresponding to the inner and outer edges relevant to that 1654abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski * triangle. 1655abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski *//*--------------------------------------------------------------------*/ 1656abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiclass InvariantOuterTriangleSetTestInstance : public InvarianceTestInstance 1657abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1658abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskipublic: 1659abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski InvariantOuterTriangleSetTestInstance (Context& context, const CaseDefinition& caseDef) : InvarianceTestInstance(context, caseDef) {} 1660abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1661abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskiprotected: 1662abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<LevelCase> genTessLevelCases (void) const 1663abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1664abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numSubCasesPerEdge = 4; 1665abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numEdges = m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 1666abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski : m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ? 4 : 0; 1667abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<LevelCase> baseResult = InvarianceTestInstance::genTessLevelCases(); 1668abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<LevelCase> result; 1669abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::Random rnd (123); 1670abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1671abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Generate variants with different values for irrelevant levels. 1672abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int baseNdx = 0; baseNdx < static_cast<int>(baseResult.size()); ++baseNdx) 1673abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1674abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const TessLevels& base = baseResult[baseNdx].levels[0]; 1675abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (base.inner[0] == 1.0f || (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS && base.inner[1] == 1.0f)) 1676abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski continue; 1677abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1678abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int edgeNdx = 0; edgeNdx < numEdges; ++edgeNdx) 1679abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1680abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessLevels levels = base; 1681abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski LevelCase levelCase; 1682abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levelCase.mem = edgeNdx; 1683abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1684abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int subCaseNdx = 0; subCaseNdx < numSubCasesPerEdge; ++subCaseNdx) 1685abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1686abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levelCase.levels.push_back(levels); 1687abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1688abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < DE_LENGTH_OF_ARRAY(levels.outer); ++i) 1689abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1690abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (i != edgeNdx) 1691abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[i] = rnd.getFloat(2.0f, 16.0f); 1692abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1693abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1694abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 1695abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.inner[1] = rnd.getFloat(2.0f, 16.0f); 1696abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1697abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1698abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.push_back(levelCase); 1699abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1700abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1701abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1702abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 1703abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1704abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1705abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski class IsTriangleTriangleOnOuterEdge 1706abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1707abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski public: 1708abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski IsTriangleTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {} 1709abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const tcu::Vec3* vertices) const 1710abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1711abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool touchesAppropriateEdge = false; 1712abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int v = 0; v < 3; ++v) 1713abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (vertices[v][m_edgeNdx] == 0.0f) 1714abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski touchesAppropriateEdge = true; 1715abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1716abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (touchesAppropriateEdge) 1717abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1718abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3 avg = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; 1719abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return avg[m_edgeNdx] < avg[(m_edgeNdx+1)%3] && 1720abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski avg[m_edgeNdx] < avg[(m_edgeNdx+2)%3]; 1721abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1722abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1723abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1724abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1725abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski private: 1726abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int m_edgeNdx; 1727abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1728abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1729abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski class IsQuadTriangleOnOuterEdge 1730abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1731abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski public: 1732abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski IsQuadTriangleOnOuterEdge (int edgeNdx) : m_edgeNdx(edgeNdx) {} 1733abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1734abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool onEdge (const tcu::Vec3& v) const 1735abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1736abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return v[m_edgeNdx%2] == (m_edgeNdx <= 1 ? 0.0f : 1.0f); 1737abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1738abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1739abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski static inline bool onAnyEdge (const tcu::Vec3& v) 1740abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1741abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return v[0] == 0.0f || v[0] == 1.0f || v[1] == 0.0f || v[1] == 1.0f; 1742abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1743abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1744abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool operator() (const tcu::Vec3* vertices) const 1745abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1746abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int v = 0; v < 3; ++v) 1747abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1748abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& a = vertices[v]; 1749abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& b = vertices[(v+1)%3]; 1750abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const tcu::Vec3& c = vertices[(v+2)%3]; 1751abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (onEdge(a) && onEdge(b)) 1752abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1753abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (onEdge(c) && !onAnyEdge(a) && !onAnyEdge(b) && a[m_edgeNdx%2] == b[m_edgeNdx%2]) 1754abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1755abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1756abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1757abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1758abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1759abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1760abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski private: 1761abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int m_edgeNdx; 1762abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski }; 1763abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1764abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool compare (const PerPrimitiveVec& primitivesA, const PerPrimitiveVec& primitivesB, const int outerEdgeNdx) const 1765abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1766abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) 1767abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1768abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, m_context.getTestContext().getLog(), 1769abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski IsTriangleTriangleOnOuterEdge(outerEdgeNdx), 1770abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ("inner triangles, and outer triangles corresponding to other edge than edge " 1771abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski + outerEdgeDescriptions(m_caseDef.primitiveType)[outerEdgeNdx].description()).c_str()); 1772abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1773abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (m_caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) 1774abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1775abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return compareTriangleSets(primitivesA, primitivesB, m_context.getTestContext().getLog(), 1776abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski IsQuadTriangleOnOuterEdge(outerEdgeNdx), 1777abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski ("inner triangles, and outer triangles corresponding to other edge than edge " 1778abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski + outerEdgeDescriptions(m_caseDef.primitiveType)[outerEdgeNdx].description()).c_str()); 1779abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1780abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 1781abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 1782abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1783abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1784abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1785abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1786abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1787abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestInstance* InvarianceTestCase::createInstance (Context& context) const 1788abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1789abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski switch (m_caseDef.caseType) 1790abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1791abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case CASETYPE_INVARIANT_PRIMITIVE_SET: return new InvariantPrimitiveSetTestInstance (context, m_caseDef); 1792abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case CASETYPE_INVARIANT_TRIANGLE_SET: return new InvariantTriangleSetTestInstance (context, m_caseDef); 1793abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case CASETYPE_INVARIANT_OUTER_TRIANGLE_SET: return new InvariantOuterTriangleSetTestInstance(context, m_caseDef); 1794abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski case CASETYPE_INVARIANT_INNER_TRIANGLE_SET: return new InvariantInnerTriangleSetTestInstance(context, m_caseDef); 1795abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski default: 1796abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 1797abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return DE_NULL; 1798abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1799abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1800abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1801abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestCase* makeInvariantPrimitiveSetTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const Winding winding, const bool usePointMode) 1802abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1803abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_INVARIANT_PRIMITIVE_SET, primitiveType, spacingMode, getWindingUsage(winding), usePointMode }; 1804abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new InvarianceTestCase(testCtx, name, description, caseDef); 1805abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1806abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1807abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestCase* makeInvariantTriangleSetTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode) 1808abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1809abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 1810abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_INVARIANT_TRIANGLE_SET, primitiveType, spacingMode, WINDING_USAGE_VARY, false }; 1811abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new InvarianceTestCase(testCtx, name, description, caseDef); 1812abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1813abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1814abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestCase* makeInvariantInnerTriangleSetTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode) 1815abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1816abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 1817abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_INVARIANT_INNER_TRIANGLE_SET, primitiveType, spacingMode, WINDING_USAGE_VARY, false }; 1818abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new InvarianceTestCase(testCtx, name, description, caseDef); 1819abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1820abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1821abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej JesionowskiTestCase* makeInvariantOuterTriangleSetTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode) 1822abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1823abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS); 1824abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_INVARIANT_OUTER_TRIANGLE_SET, primitiveType, spacingMode, WINDING_USAGE_VARY, false }; 1825abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return new InvarianceTestCase(testCtx, name, description, caseDef); 1826abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1827abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1828abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // PrimitiveSetInvariance ns 1829abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1830abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskinamespace TessCoordComponent 1831abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1832abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1833abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskienum CaseType 1834abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1835abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_TESS_COORD_RANGE = 0, //!< Test that all (relevant) components of tess coord are in [0,1]. 1836abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_ONE_MINUS_TESS_COORD, //!< Test that for every (relevant) component c of a tess coord, 1.0-c is exact. 1837abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1838abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CASETYPE_LAST 1839abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1840abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1841abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistruct CaseDefinition 1842abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1843abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CaseType caseType; 1844abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessPrimitiveType primitiveType; 1845abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski SpacingMode spacingMode; 1846abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Winding winding; 1847abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski bool usePointMode; 1848abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski}; 1849abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1850abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskistd::vector<TessLevels> genTessLevelCases (const int numCases) 1851abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1852abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::Random rnd(123); 1853abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::vector<TessLevels> result; 1854abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1855abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numCases; ++i) 1856abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1857abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski TessLevels levels; 1858abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.inner[0] = rnd.getFloat(1.0f, 63.0f); 1859abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.inner[1] = rnd.getFloat(1.0f, 63.0f); 1860abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[0] = rnd.getFloat(1.0f, 63.0f); 1861abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[1] = rnd.getFloat(1.0f, 63.0f); 1862abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[2] = rnd.getFloat(1.0f, 63.0f); 1863abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski levels.outer[3] = rnd.getFloat(1.0f, 63.0f); 1864abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski result.push_back(levels); 1865abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1866abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1867abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return result; 1868abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1869abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1870abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitypedef bool (*CompareFunc)(tcu::TestLog& log, const float value); 1871abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1872abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool compareTessCoordRange (tcu::TestLog& log, const float value) 1873abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1874abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!de::inRange(value, 0.0f, 1.0f)) 1875abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1876abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Failure: tess coord component isn't in range [0,1]" << tcu::TestLog::EndMessage; 1877abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1878abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1879abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1880abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1881abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1882abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskibool compareOneMinusTessCoord (tcu::TestLog& log, const float value) 1883abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1884abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (value != 1.0f) 1885abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1886abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Failure: comp + (1.0-comp) doesn't equal 1.0 for some component of tessellation coordinate" << tcu::TestLog::EndMessage; 1887abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return false; 1888abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1889abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return true; 1890abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1891abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1892abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskivoid initPrograms (vk::SourceCollections& programCollection, const CaseDefinition caseDef) 1893abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1894abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Vertex shader 1895abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1896abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 1897abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 1898abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1899abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) in highp float in_v_attr;\n" 1900abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) out highp float in_tc_attr;\n" 1901abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1902abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 1903abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 1904abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " in_tc_attr = in_v_attr;\n" 1905abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 1906abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1907abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 1908abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1909abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1910abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Tessellation control shader 1911abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1912abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 1913abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 1914abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "#extension GL_EXT_tessellation_shader : require\n" 1915abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1916abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(vertices = 1) out;\n" 1917abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1918abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(location = 0) in highp float in_tc_attr[];\n" 1919abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1920abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 1921abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 1922abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelInner[0] = in_tc_attr[0];\n" 1923abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelInner[1] = in_tc_attr[1];\n" 1924abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1925abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[0] = in_tc_attr[2];\n" 1926abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[1] = in_tc_attr[3];\n" 1927abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[2] = in_tc_attr[4];\n" 1928abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " gl_TessLevelOuter[3] = in_tc_attr[5];\n" 1929abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 1930abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1931abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()); 1932abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1933abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1934abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Tessellation evaluation shader 1935abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1936abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream tessCoordSrc; 1937abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1938abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (caseDef.caseType == CASETYPE_TESS_COORD_RANGE) 1939abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessCoordSrc << " sb_out.tessCoord[index] = gl_TessCoord;\n"; 1940abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else if (caseDef.caseType == CASETYPE_ONE_MINUS_TESS_COORD) 1941abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1942abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const char* components[] = { "x" , "y", "z" }; 1943abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numComponents = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 2); 1944abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1945abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numComponents; ++i) 1946abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessCoordSrc << " {\n" 1947abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " float oneMinusComp = 1.0 - gl_TessCoord." << components[i] << ";\n" 1948abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " sb_out.tessCoord[index]." << components[i] << " = gl_TessCoord." << components[i] << " + oneMinusComp;\n" 1949abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " }\n"; 1950abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1951abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski else 1952abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 1953abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(false); 1954abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return; 1955abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1956abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1957abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski std::ostringstream src; 1958abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" 1959abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "#extension GL_EXT_tessellation_shader : require\n" 1960abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1961abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", " 1962abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getSpacingModeShaderName(caseDef.spacingMode) << ", " 1963abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << getWindingShaderName(caseDef.winding) 1964abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << (caseDef.usePointMode ? ", point_mode" : "") << ") in;\n" 1965abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1966abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "layout(set = 0, binding = 0, std430) coherent restrict buffer Output {\n" 1967abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int numInvocations;\n" 1968abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " vec3 tessCoord[];\n" 1969abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "} sb_out;\n" 1970abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "\n" 1971abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "void main (void)\n" 1972abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "{\n" 1973abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << " int index = atomicAdd(sb_out.numInvocations, 1);\n" 1974abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tessCoordSrc.str() 1975abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "}\n"; 1976abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1977abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()); 1978abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 1979abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 1980abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1981abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestStatus test (Context& context, const CaseDefinition caseDef) 1982abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 1983abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER | FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); 1984abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1985abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const DeviceInterface& vk = context.getDeviceInterface(); 1986abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDevice device = context.getDevice(); 1987abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkQueue queue = context.getUniversalQueue(); 1988abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 1989abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski Allocator& allocator = context.getDefaultAllocator(); 1990abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1991abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numTessLevelCases = 32; 1992abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<TessLevels> tessLevelCases = genTessLevelCases(numTessLevelCases); 1993abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1994abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski int maxNumVerticesInDrawCall = 0; 1995abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numTessLevelCases; ++i) 1996abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski maxNumVerticesInDrawCall = de::max(maxNumVerticesInDrawCall, referenceVertexCount(caseDef.primitiveType, caseDef.spacingMode, caseDef.usePointMode, 1997abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski &tessLevelCases[i].inner[0], &tessLevelCases[i].outer[0])); 1998abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 1999abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // We may get more invocations than expected, so add some more space (arbitrary number). 2000abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski maxNumVerticesInDrawCall += 4; 2001abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2002abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Vertex input attributes buffer: to pass tessellation levels 2003abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2004abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkFormat vertexFormat = VK_FORMAT_R32_SFLOAT; 2005abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deUint32 vertexStride = tcu::getPixelSize(mapVkFormat(vertexFormat)); 2006abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize vertexDataSizeBytes = NUM_TESS_LEVELS * vertexStride; 2007abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer vertexBuffer (vk, device, allocator, makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible); 2008abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2009abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(vertexDataSizeBytes == sizeof(TessLevels)); 2010abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2011abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Output buffer: number of invocations and array of tess coords 2012abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 20136e5ef4c51158771e71f72c70980b4dbd78f011f2Pyry Haulos const int resultBufferTessCoordsOffset = (int)sizeof(deInt32) * 4; 2014abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize resultBufferSizeBytes = resultBufferTessCoordsOffset + maxNumVerticesInDrawCall * sizeof(tcu::Vec4); 2015abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Buffer resultBuffer (vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); 2016abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2017abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Descriptors 2018abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2019abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder() 2020abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 2021abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(vk, device)); 2022abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2023abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder() 2024abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 2025abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 2026abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2027abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); 2028abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes); 2029abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2030abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DescriptorSetUpdateBuilder() 2031abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo) 2032abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .update(vk, device); 2033abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2034abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkRenderPass> renderPass (makeRenderPassWithoutAttachments (vk, device)); 2035abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkFramebuffer> framebuffer (makeFramebufferWithoutAttachments(vk, device, *renderPass)); 2036abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout (vk, device, *descriptorSetLayout)); 2037abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkCommandPool> cmdPool (makeCommandPool (vk, device, queueFamilyIndex)); 203855dd4426673bd260dde56addcfea802f21c31304Mika Isojärvi const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 2039abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2040abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Unique<VkPipeline> pipeline(GraphicsPipelineBuilder() 2041abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setPatchControlPoints (NUM_TESS_LEVELS) 2042abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setVertexInputSingleAttribute(vertexFormat, vertexStride) 2043abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("vert"), DE_NULL) 2044abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get("tesc"), DE_NULL) 2045abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get("tese"), DE_NULL) 2046abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski .build (vk, device, *pipelineLayout, *renderPass)); 2047abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2048abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < numTessLevelCases; ++tessLevelCaseNdx) 2049abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2050abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski context.getTestContext().getLog() 2051abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::Message 2052abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << "Testing with tessellation levels: " << getTessellationLevelsString(tessLevelCases[tessLevelCaseNdx], caseDef.primitiveType) 2053abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << tcu::TestLog::EndMessage; 2054abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2055abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2056abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = vertexBuffer.getAllocation(); 2057abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemcpy(alloc.getHostPtr(), &tessLevelCases[tessLevelCaseNdx], sizeof(TessLevels)); 2058abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(TessLevels)); 2059abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2060abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2061abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& alloc = resultBuffer.getAllocation(); 2062abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski deMemset(alloc.getHostPtr(), 0, static_cast<std::size_t>(resultBufferSizeBytes)); 2063abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes); 2064abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2065abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2066abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginCommandBuffer(vk, *cmdBuffer); 2067abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski beginRenderPassWithRasterizationDisabled(vk, *cmdBuffer, *renderPass, *framebuffer); 2068abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2069abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 2070abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 2071abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2072abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkDeviceSize vertexBufferOffset = 0ull; 2073abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 2074abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2075abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2076abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdDraw(*cmdBuffer, NUM_TESS_LEVELS, 1u, 0u, 0u); 2077abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endRenderPass(vk, *cmdBuffer); 2078abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2079abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2080abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( 2081abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes); 2082abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2083abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 2084abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL); 2085abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2086abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2087abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski endCommandBuffer(vk, *cmdBuffer); 2088abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski submitCommandsAndWait(vk, device, queue, *cmdBuffer); 2089abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2090abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // Verify case result 2091abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2092abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Allocation& resultAlloc = resultBuffer.getAllocation(); 2093abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), resultBufferSizeBytes); 2094abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2095abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const deInt32 numVertices = *static_cast<deInt32*>(resultAlloc.getHostPtr()); 2096abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::vector<tcu::Vec3> vertices = readInterleavedData<tcu::Vec3>(numVertices, resultAlloc.getHostPtr(), resultBufferTessCoordsOffset, sizeof(tcu::Vec4)); 2097abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2098abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski // If this fails then we didn't read all vertices from shader and test must be changed to allow more. 2099abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(numVertices <= maxNumVerticesInDrawCall); 2100abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2101abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestLog& log = context.getTestContext().getLog(); 2102abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const int numComponents = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 2); 2103abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2104abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski CompareFunc compare = (caseDef.caseType == CASETYPE_TESS_COORD_RANGE ? compareTessCoordRange : 2105abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski caseDef.caseType == CASETYPE_ONE_MINUS_TESS_COORD ? compareOneMinusTessCoord : DE_NULL); 2106abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2107abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski DE_ASSERT(compare != DE_NULL); 2108abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2109abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (std::vector<tcu::Vec3>::const_iterator vertexIter = vertices.begin(); vertexIter != vertices.end(); ++vertexIter) 2110abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int i = 0; i < numComponents; ++i) 2111abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (!compare(log, (*vertexIter)[i])) 2112abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2113abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski log << tcu::TestLog::Message << "Note: got a wrong tessellation coordinate " 2114abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski << (numComponents == 3 ? de::toString(*vertexIter) : de::toString(vertexIter->swizzle(0,1))) << tcu::TestLog::EndMessage; 2115abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2116abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tcu::TestStatus::fail("Invalid tessellation coordinate component"); 2117abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2118abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2119abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2120abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return tcu::TestStatus::pass("OK"); 2121abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 2122abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2123abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCase* makeTessCoordRangeTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const Winding winding, const bool usePointMode) 2124abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 2125abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_TESS_COORD_RANGE, primitiveType, spacingMode, winding, usePointMode }; 2126abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return createFunctionCaseWithPrograms(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, description, initPrograms, test, caseDef); 2127abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 2128abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2129abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCase* makeOneMinusTessCoordTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const Winding winding, const bool usePointMode) 2130abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 2131abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const CaseDefinition caseDef = { CASETYPE_ONE_MINUS_TESS_COORD, primitiveType, spacingMode, winding, usePointMode }; 2132abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return createFunctionCaseWithPrograms(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, description, initPrograms, test, caseDef); 2133abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 2134abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2135abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // TessCoordComponent ns 2136abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2137abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // anonymous 2138abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2139abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! These tests correspond to dEQP-GLES31.functional.tessellation.invariance.* 2140abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! Original OpenGL ES tests used transform feedback to get vertices in primitive order. To emulate this behavior we have to use geometry shader, 2141abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! which allows us to intercept verticess of final output primitives. This can't be done with tessellation shaders alone as number and order of 2142abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski//! invocation is undefined. 2143abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowskitcu::TestCaseGroup* createInvarianceTests (tcu::TestContext& testCtx) 2144abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski{ 2145abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "invariance", "Test tessellation invariance rules")); 2146abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2147abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> invariantPrimitiveSetGroup (new tcu::TestCaseGroup(testCtx, "primitive_set", "Test invariance rule #1")); 2148abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> invariantOuterEdgeGroup (new tcu::TestCaseGroup(testCtx, "outer_edge_division", "Test invariance rule #2")); 2149abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> symmetricOuterEdgeGroup (new tcu::TestCaseGroup(testCtx, "outer_edge_symmetry", "Test invariance rule #3")); 2150abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> outerEdgeVertexSetIndexIndependenceGroup(new tcu::TestCaseGroup(testCtx, "outer_edge_index_independence", "Test invariance rule #4")); 2151abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> invariantTriangleSetGroup (new tcu::TestCaseGroup(testCtx, "triangle_set", "Test invariance rule #5")); 2152abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> invariantInnerTriangleSetGroup (new tcu::TestCaseGroup(testCtx, "inner_triangle_set", "Test invariance rule #6")); 2153abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> invariantOuterTriangleSetGroup (new tcu::TestCaseGroup(testCtx, "outer_triangle_set", "Test invariance rule #7")); 2154abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> tessCoordComponentRangeGroup (new tcu::TestCaseGroup(testCtx, "tess_coord_component_range", "Test invariance rule #8, first part")); 2155abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski de::MovePtr<tcu::TestCaseGroup> oneMinusTessCoordComponentGroup (new tcu::TestCaseGroup(testCtx, "one_minus_tess_coord_component", "Test invariance rule #8, second part")); 2156abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2157abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int primitiveTypeNdx = 0; primitiveTypeNdx < TESSPRIMITIVETYPE_LAST; ++primitiveTypeNdx) 2158abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx) 2159abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2160abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const TessPrimitiveType primitiveType = static_cast<TessPrimitiveType>(primitiveTypeNdx); 2161abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const SpacingMode spacingMode = static_cast<SpacingMode>(spacingModeNdx); 2162abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool triOrQuad = primitiveType == TESSPRIMITIVETYPE_TRIANGLES || primitiveType == TESSPRIMITIVETYPE_QUADS; 2163abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::string primName = getTessPrimitiveTypeShaderName(primitiveType); 2164abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::string primSpacName = primName + "_" + getSpacingModeShaderName(spacingMode); 2165abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2166abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (triOrQuad) 2167abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2168abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invariantOuterEdgeGroup->addChild ( InvariantOuterEdge::makeOuterEdgeDivisionTest (testCtx, primSpacName, "", primitiveType, spacingMode)); 2169abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invariantTriangleSetGroup->addChild (PrimitiveSetInvariance::makeInvariantTriangleSetTest (testCtx, primSpacName, "", primitiveType, spacingMode)); 2170abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invariantInnerTriangleSetGroup->addChild(PrimitiveSetInvariance::makeInvariantInnerTriangleSetTest(testCtx, primSpacName, "", primitiveType, spacingMode)); 2171abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invariantOuterTriangleSetGroup->addChild(PrimitiveSetInvariance::makeInvariantOuterTriangleSetTest(testCtx, primSpacName, "", primitiveType, spacingMode)); 2172abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2173abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2174abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int windingNdx = 0; windingNdx < WINDING_LAST; ++windingNdx) 2175abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski for (int usePointModeNdx = 0; usePointModeNdx <= 1; ++usePointModeNdx) 2176abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski { 2177abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const Winding winding = static_cast<Winding>(windingNdx); 2178abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const bool usePointMode = (usePointModeNdx != 0); 2179abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski const std::string primSpacWindPointName = primSpacName + "_" + getWindingShaderName(winding) + (usePointMode ? "_point_mode" : ""); 2180abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2181abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski invariantPrimitiveSetGroup->addChild (PrimitiveSetInvariance::makeInvariantPrimitiveSetTest(testCtx, primSpacWindPointName, "", primitiveType, spacingMode, winding, usePointMode)); 2182abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski tessCoordComponentRangeGroup->addChild ( TessCoordComponent::makeTessCoordRangeTest (testCtx, primSpacWindPointName, "", primitiveType, spacingMode, winding, usePointMode)); 2183abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski oneMinusTessCoordComponentGroup->addChild( TessCoordComponent::makeOneMinusTessCoordTest (testCtx, primSpacWindPointName, "", primitiveType, spacingMode, winding, usePointMode)); 2184abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski symmetricOuterEdgeGroup->addChild ( InvariantOuterEdge::makeSymmetricOuterEdgeTest (testCtx, primSpacWindPointName, "", primitiveType, spacingMode, winding, usePointMode)); 2185abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2186abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski if (triOrQuad) 2187abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski outerEdgeVertexSetIndexIndependenceGroup->addChild(InvariantOuterEdge::makeOuterEdgeIndexIndependenceTest(testCtx, primSpacWindPointName, "", primitiveType, spacingMode, winding, usePointMode)); 2188abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2189abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski } 2190abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2191abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(invariantPrimitiveSetGroup.release()); 2192abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(invariantOuterEdgeGroup.release()); 2193abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(symmetricOuterEdgeGroup.release()); 2194abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(outerEdgeVertexSetIndexIndependenceGroup.release()); 2195abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(invariantTriangleSetGroup.release()); 2196abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(invariantInnerTriangleSetGroup.release()); 2197abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(invariantOuterTriangleSetGroup.release()); 2198abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(tessCoordComponentRangeGroup.release()); 2199abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski group->addChild(oneMinusTessCoordComponentGroup.release()); 2200abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2201abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski return group.release(); 2202abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} 2203abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski 2204abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // tessellation 2205abbf1c4efd3388dcfe59d125e5f33140c444a53aMaciej Jesionowski} // vkt 2206