13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.1 Module 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Tessellation and geometry shader interaction stress tests. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31sTessellationGeometryInteractionTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Stress 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AllowedRenderFailureException : public std::runtime_error 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry AllowedRenderFailureException (const char* message) : std::runtime_error(message) { } 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GridRenderCase : public TestCase 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum Flags 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_MAX_SPEC = 0x0001, 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_MAX_IMPLEMENTATION = 0x0002, 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_MAX_SPEC = 0x0004, 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_MAX_IMPLEMENTATION = 0x0008, 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC = 0x0010, 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION = 0x0020, 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase (Context& context, const char* name, const char* description, int flags); 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~GridRenderCase (void); 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTo (std::vector<tcu::Surface>& dst); 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verifyResultLayer (int layerNdx, const tcu::Surface& dst); 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getVertexSource (void); 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getFragmentSource (void); 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationControlSource (int tessLevel); 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationEvaluationSource (int tessLevel); 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getGeometryShaderSource (int numPrimitives, int numInstances); 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 256 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_flags; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numLayers; 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::GridRenderCase (Context& context, const char* name, const char* description, int flags) 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_flags (flags) 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numLayers (1) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_TESSELLATION_MAX_SPEC) == 0) || ((m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) == 0)); 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_GEOMETRY_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) == 0)); 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) == 0)); 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::~GridRenderCase (void) 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::init (void) 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Requirements 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderTarget().getHeight() < RENDER_SIZE) 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target."); 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Testing tessellation and geometry shaders that output a large number of primitives.\n" 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << getDescription() 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Gen program 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int tessGenLevel = -1; 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::VertexSource(getVertexSource()) 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()); 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Tessellation limits 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_TESS_GEN_LEVEL, &tessGenLevel); 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query tessellation limits"); 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_TESSELLATION_MAX_SPEC) 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessGenLevel = 64; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessGenLevel = 5; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Tessellation level: " << tessGenLevel << ", mode = quad.\n" 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tEach input patch produces " << (tessGenLevel*tessGenLevel) << " (" << (tessGenLevel*tessGenLevel*2) << " triangles)\n" 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TessellationControlSource(getTessellationControlSource(tessGenLevel)) 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource(tessGenLevel)); 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Geometry limits 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryOutputComponents = -1; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryOutputVertices = -1; 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryTotalOutputComponents = -1; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryShaderInvocations = -1; 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool logGeometryLimits = false; 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool logInvocationLimits = false; 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Using implementation maximum geometry shader output limits." << tcu::TestLog::EndMessage; 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &geometryOutputComponents); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &geometryOutputVertices); 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &geometryTotalOutputComponents); 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry limits"); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logGeometryLimits = true; 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_MAX_SPEC) 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Using geometry shader extension minimum maximum output limits." << tcu::TestLog::EndMessage; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputComponents = 128; 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputVertices = 256; 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryTotalOutputComponents = 1024; 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logGeometryLimits = true; 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputComponents = 128; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputVertices = 16; 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryTotalOutputComponents = 1024; 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &geometryShaderInvocations); 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry invocation limits"); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logInvocationLimits = true; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryShaderInvocations = 32; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logInvocationLimits = true; 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryShaderInvocations = 4; 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logGeometryLimits || logInvocationLimits) 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MessageBuilder msg(&m_testCtx.getLog()); 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "Geometry shader, targeting following limits:\n"; 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logGeometryLimits) 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "\tGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = " << geometryOutputComponents << "\n" 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tGL_MAX_GEOMETRY_OUTPUT_VERTICES = " << geometryOutputVertices << "\n" 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << geometryTotalOutputComponents << "\n"; 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logInvocationLimits) 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "\tGL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << geometryShaderInvocations; 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << tcu::TestLog::EndMessage; 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numComponentsPerVertex = 8; // vec4 pos, vec4 color 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If FLAG_GEOMETRY_SEPARATE_PRIMITIVES is not set, geometry shader fills a rectangle area in slices. 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Each slice is a triangle strip and is generated by a single shader invocation. 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // One slice with 4 segment ends (nodes) and 3 segments: 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .__.__.__. 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // |\ |\ |\ | 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // |_\|_\|_\| 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodesComponentLimit = geometryTotalOutputComponents / (2 * numComponentsPerVertex); // each node 2 vertices 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodesOutputLimit = geometryOutputVertices / 2; // each node 2 vertices 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodes = de::min(numSliceNodesComponentLimit, numSliceNodesOutputLimit); 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVerticesPerInvocation = numSliceNodes * 2; 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrimitivesPerInvocation = (numSliceNodes - 1) * 2; 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int geometryVerticesPerPrimitive = numVerticesPerInvocation * geometryShaderInvocations; 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int geometryPrimitivesOutPerPrimitive = numPrimitivesPerInvocation * geometryShaderInvocations; 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Geometry shader:\n" 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output vertex count per invocation: " << (numVerticesPerInvocation) << "\n" 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output primitive count per invocation: " << (numPrimitivesPerInvocation) << "\n" 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tNumber of invocations per primitive: " << geometryShaderInvocations << "\n" 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output vertex count per input primitive: " << (geometryVerticesPerPrimitive) << "\n" 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output primitive count per input primitive: " << (geometryPrimitivesOutPerPrimitive) << "\n" 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::GeometrySource(getGeometryShaderSource(numPrimitivesPerInvocation, geometryShaderInvocations)); 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Program:\n" 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal program output vertices count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryVerticesPerPrimitive) << "\n" 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal program output primitive count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryPrimitivesOutPerPrimitive) << "\n" 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources); 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("failed to build program"); 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::deinit (void) 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::IterateResult GridRenderCase::iterate (void) 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<tcu::Surface> renderedLayers (m_numLayers); 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allLayersOk = true; 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numLayers; ++ndx) 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderedLayers[ndx].setSize(RENDER_SIZE, RENDER_SIZE); 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering single point at the origin. Expecting yellow and green colored grid-like image. (High-frequency grid may appear unicolored)." << tcu::TestLog::EndMessage; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTo(renderedLayers); 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const AllowedRenderFailureException& ex) 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Got accepted failure 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Could not render, reason: " << ex.what() << "\n" 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Failure is allowed." 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numLayers; ++ndx) 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allLayersOk &= verifyResultLayer(ndx, renderedLayers[ndx]); 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allLayersOk) 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::renderTo (std::vector<tcu::Surface>& dst) 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position"); 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (positionLocation == -1) 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Attribute a_position location was -1"); 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, dst.front().getWidth(), dst.front().getHeight()); 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "viewport"); 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao"); 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f); 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clear viewport 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // draw 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum glerror; 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 1); 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // allow always OOM 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glerror = gl.getError(); 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glerror == GL_OUT_OF_MEMORY) 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw AllowedRenderFailureException("got GL_OUT_OF_MEMORY while drawing"); 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(glerror, "draw patches"); 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read layers 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst.front().getAccess()); 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels"); 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool GridRenderCase::verifyResultLayer (int layerNdx, const tcu::Surface& image) 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface errorMask (image.getWidth(), image.getHeight()); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool foundError = false; 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output layer " << layerNdx << tcu::TestLog::EndMessage; 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < image.getHeight(); ++y) 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < image.getWidth(); ++x) 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int threshold = 8; 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::RGBA color = image.getPixel(x, y); 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Color must be a linear combination of green and yellow 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (color.getGreen() < 255 - threshold || color.getBlue() > threshold) 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 397c215aaa83047ebbaabafef7acd71275a256da6abDejan Mircevski errorMask.setPixel(x, y, tcu::RGBA::red()); 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry foundError = true; 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!foundError) 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message << "Image valid." << tcu::TestLog::EndMessage 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::ImageSet("ImageVerification", "Image verification") 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("Result", "Rendered result", image.getAccess()) 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndImageSet; 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message << "Image verification failed, found invalid pixels." << tcu::TestLog::EndMessage 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::ImageSet("ImageVerification", "Image verification") 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("Result", "Rendered result", image.getAccess()) 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess()) 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndImageSet; 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getVertexSource (void) 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 a_position;\n" 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = a_position;\n" 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getFragmentSource (void) 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "flat in mediump vec4 v_color;\n" 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(location = 0) out mediump vec4 fragColor;\n" 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " fragColor = v_color;\n" 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationControlSource (int tessLevel) 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices=1) out;\n" 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = " << tessLevel << ".0;\n" 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = " << tessLevel << ".0;\n" 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = " << tessLevel << ".0;\n" 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = " << tessLevel << ".0;\n" 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = " << tessLevel << ".0;\n" 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = " << tessLevel << ".0;\n" 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationEvaluationSource (int tessLevel) 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(quads) in;\n" 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump ivec2 v_tessellationGridPosition;\n" 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4760a0dd88d111d0bfcecd63d3cb19c3f428c04ca82Jarkko Pöyry "// note: No need to use precise gl_Position since position does not depend on order\n" 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Fill the whole viewport\n" 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.x * 2.0 - 1.0, gl_TessCoord.y * 2.0 - 1.0, 0.0, 1.0);\n" 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Calculate position in tessellation grid\n" 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_tessellationGridPosition = ivec2(round(gl_TessCoord.xy * float(" << tessLevel << ")));\n" 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getGeometryShaderSource (int numPrimitives, int numInstances) 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(triangles, invocations=" << numInstances << ") in;\n" 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(triangle_strip, max_vertices=" << (numPrimitives + 2) << ") out;\n" 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump ivec2 v_tessellationGridPosition[];\n" 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "flat out highp vec4 v_color;\n" 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main ()\n" 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const float equalThreshold = 0.001;\n" 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const float gapOffset = 0.0001; // subdivision performed by the geometry shader might produce gaps. Fill potential gaps by enlarging the output slice a little.\n" 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Input triangle is generated from an axis-aligned rectangle by splitting it in half\n" 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Original rectangle can be found by finding the bounding AABB of the triangle\n" 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 aabb = vec4(min(gl_in[0].gl_Position.x, min(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n" 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " min(gl_in[0].gl_Position.y, min(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)),\n" 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " max(gl_in[0].gl_Position.x, max(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n" 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " max(gl_in[0].gl_Position.y, max(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)));\n" 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Location in tessellation grid\n" 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 gridPosition = ivec2(min(v_tessellationGridPosition[0], min(v_tessellationGridPosition[1], v_tessellationGridPosition[2])));\n" 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Which triangle of the two that split the grid cell\n" 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " int numVerticesOnBottomEdge = 0;\n" 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < 3; ++ndx)\n" 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (abs(gl_in[ndx].gl_Position.y - aabb.w) < equalThreshold)\n" 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ++numVerticesOnBottomEdge;\n" 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " bool isBottomTriangle = numVerticesOnBottomEdge == 2;\n" 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Fill the input area with slices\n" 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Upper triangle produces slices only to the upper half of the quad and vice-versa\n" 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float triangleOffset = (isBottomTriangle) ? ((aabb.w + aabb.y) / 2.0) : (aabb.y);\n" 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Each slice is a invocation\n" 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float sliceHeight = (aabb.w - aabb.y) / float(2 * " << numInstances << ");\n" 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float invocationOffset = float(gl_InvocationID) * sliceHeight;\n" 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputSliceArea;\n" 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.x = aabb.x - gapOffset;\n" 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.y = triangleOffset + invocationOffset - gapOffset;\n" 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.z = aabb.z + gapOffset;\n" 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.w = triangleOffset + invocationOffset + sliceHeight + gapOffset;\n""\n" 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Draw slice\n" 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < " << ((numPrimitives+2)/2) << "; ++ndx)\n" 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n" 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputColor = (((gl_InvocationID + ndx) % 2) == 0) ? (green) : (yellow);\n" 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float xpos = mix(outputSliceArea.x, outputSliceArea.z, float(ndx) / float(" << (numPrimitives/2) << "));\n" 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(xpos, outputSliceArea.y, 0.0, 1.0);\n" 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(xpos, outputSliceArea.w, 0.0, 1.0);\n" 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n" 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::TessellationGeometryInteractionTests (Context& context) 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "tessellation_geometry_interaction", "Tessellation and geometry shader interaction stress tests") 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5623c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::~TessellationGeometryInteractionTests (void) 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessellationGeometryInteractionTests::init (void) 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const multilimitGroup = new tcu::TestCaseGroup(m_testCtx, "render_multiple_limits", "Various render tests"); 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(multilimitGroup); 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .render_multiple_limits 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct LimitCaseDef 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* desc; 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int flags; 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } cases[] = 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Test multiple limits at the same time 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_tessellation_max_geometry", 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Minimum maximum tessellation level and geometry shader output vertices", 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_tessellation_max_geometry", 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Maximum tessellation level and geometry shader output vertices supported by the implementation", 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_tessellation_max_invocations", 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Minimum maximum tessellation level and geometry shader invocations", 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_tessellation_max_invocations", 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Maximum tessellation level and geometry shader invocations supported by the implementation", 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_geometry_max_invocations", 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Minimum maximum geometry shader output vertices and invocations", 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_geometry_max_invocations", 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Maximum geometry shader output vertices and invocations invocations supported by the implementation", 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Test all limits simultaneously 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_max_required", 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Output minimum maximum number of vertices", 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_MAX_SPEC | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_max_implementation", 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Output maximum number of vertices supported by the implementation", 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION | GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ++ndx) 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry multilimitGroup->addChild(new GridRenderCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].flags)); 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Stress 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 635