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 tests. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es31fTessellationGeometryInteractionTests.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuSurface.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluStrUtil.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextInfo.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluObjectWrapper.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp" 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp" 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream> 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator> 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles31 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_positionVertexShader = "#version 310 es\n" 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 a_position;\n" 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = a_position;\n" 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* const s_whiteOutputFragmentShader = "#version 310 es\n" 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(location = 0) out mediump vec4 fragColor;\n" 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " fragColor = vec4(1.0);\n" 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isBlack (const tcu::RGBA& c) 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return c.getRed() == 0 && c.getGreen() == 0 && c.getBlue() == 0; 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IdentityShaderCase : public TestCase 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IdentityShaderCase (Context& context, const char* name, const char* description); 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getVertexSource (void) const; 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getFragmentSource (void) const; 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityShaderCase::IdentityShaderCase (Context& context, const char* name, const char* description) 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase(context, name, description) 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* IdentityShaderCase::getVertexSource (void) const 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 a_position;\n" 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_vertex_color;\n" 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = a_position;\n" 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_vertex_color = vec4(a_position.x * 0.5 + 0.5, a_position.y * 0.5 + 0.5, 1.0, 0.4);\n" 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* IdentityShaderCase::getFragmentSource (void) const 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump vec4 v_fragment_color;\n" 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(location = 0) out mediump vec4 fragColor;\n" 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " fragColor = v_fragment_color;\n" 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IdentityGeometryShaderCase : public IdentityShaderCase 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseType 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASE_TRIANGLES = 0, 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASE_QUADS, 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASE_ISOLINES, 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IdentityGeometryShaderCase (Context& context, const char* name, const char* description, CaseType caseType); 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~IdentityGeometryShaderCase (void); 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationControlSource (void) const; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationEvaluationSource (bool geometryActive) const; 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getGeometrySource (void) const; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 128, 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseType m_case; 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_patchBuffer; 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityGeometryShaderCase::IdentityGeometryShaderCase (Context& context, const char* name, const char* description, CaseType caseType) 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : IdentityShaderCase (context, name, description) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_case (caseType) 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_patchBuffer (0) 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityGeometryShaderCase::~IdentityGeometryShaderCase (void) 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IdentityGeometryShaderCase::init (void) 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Requirements 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderTarget().getHeight() < RENDER_SIZE) 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target."); 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Testing tessellating shader program output does not change when a passthrough geometry shader is attached.\n" 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Rendering two images, first with and second without a geometry shader. Expecting similar results.\n" 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Using additive blending to detect overlap.\n" 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Resources 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const tcu::Vec4 patchBufferData[4] = 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( -0.9f, -0.9f, 0.0f, 1.0f ), 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( -0.9f, 0.9f, 0.0f, 1.0f ), 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.9f, -0.9f, 0.0f, 1.0f ), 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.9f, 0.9f, 0.0f, 1.0f ), 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_patchBuffer); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer); 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, sizeof(patchBufferData), patchBufferData, GL_STATIC_DRAW); 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer"); 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IdentityGeometryShaderCase::deinit (void) 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_patchBuffer) 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_patchBuffer); 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_patchBuffer = 0; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityGeometryShaderCase::IterateResult IdentityGeometryShaderCase::iterate (void) 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float innerTessellationLevel = 14.0f; 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float outerTessellationLevel = 14.0f; 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resultWithGeometry (RENDER_SIZE, RENDER_SIZE); 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resultWithoutGeometry (RENDER_SIZE, RENDER_SIZE); 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description; 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool containsGeometryShader; 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::PixelBufferAccess surfaceAccess; 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } renderTargets[] = 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "RenderWithGeometryShader", "Render with geometry shader", true, resultWithGeometry.getAccess() }, 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "RenderWithoutGeometryShader", "Render without geometry shader", false, resultWithoutGeometry.getAccess() }, 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE); 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set viewport"); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_BLEND); 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendFunc(GL_SRC_ALPHA, GL_ONE); 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendEquation(GL_FUNC_ADD); 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set blend"); 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Tessellation level: inner " << innerTessellationLevel << ", outer " << outerTessellationLevel << tcu::TestLog::EndMessage; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // render with and without geometry shader 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++renderNdx) 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), renderTargets[renderNdx].name, renderTargets[renderNdx].description); 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::VertexSource(getVertexSource()) 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource(getTessellationControlSource()) 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource(renderTargets[renderNdx].containsGeometryShader)); 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderTargets[renderNdx].containsGeometryShader) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::GeometrySource(getGeometrySource()); 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ShaderProgram program (m_context.getRenderContext(), sources); 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int posLocation = gl.getAttribLocation(program.getProgram(), "a_position"); 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int innerTessellationLoc = gl.getUniformLocation(program.getProgram(), "u_innerTessellationLevel"); 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outerTessellationLoc = gl.getUniformLocation(program.getProgram(), "u_outerTessellationLevel"); 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << program; 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program.isOk()) 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (posLocation == -1) 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("a_position location was -1"); 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (outerTessellationLoc == -1) 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("u_outerTessellationLevel location was -1"); 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(posLocation); 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs"); 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(program.getProgram()); 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(outerTessellationLoc, outerTessellationLevel); 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (innerTessellationLoc == -1) 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.uniform1f(innerTessellationLoc, innerTessellationLevel); 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, (m_case == CASE_TRIANGLES) ? (3): (4)); 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 4); 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches"); 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, renderTargets[renderNdx].surfaceAccess); 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tcu::intThresholdPositionDeviationCompare(m_testCtx.getLog(), 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "ImageCompare", 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Image comparison", 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithoutGeometry.getAccess(), 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithGeometry.getAccess(), 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec4(8, 8, 8, 255), 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec3(1, 1, 0), 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true, 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_RESULT)) 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityGeometryShaderCase::getTessellationControlSource (void) const 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices = 4) out;\n" 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform highp float u_innerTessellationLevel;\n" 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform highp float u_outerTessellationLevel;\n" 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_vertex_color[];\n" 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_patch_color[];\n" 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_patch_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n" 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n"; 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_case == CASE_TRIANGLES) 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n" 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n" 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = u_outerTessellationLevel;\n" 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = u_innerTessellationLevel;\n"; 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_QUADS) 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n" 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n" 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = u_outerTessellationLevel;\n" 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = u_outerTessellationLevel;\n" 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = u_innerTessellationLevel;\n" 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = u_innerTessellationLevel;\n"; 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_ISOLINES) 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = u_outerTessellationLevel;\n" 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = u_outerTessellationLevel;\n"; 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityGeometryShaderCase::getTessellationEvaluationSource (bool geometryActive) const 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const colorOutputName = ((geometryActive) ? ("v_evaluated_color") : ("v_fragment_color")); 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_case == CASE_TRIANGLES) ? ("triangles") : (m_case == CASE_QUADS) ? ("quads") : ("isolines")) 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ") in;\n" 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_patch_color[];\n" 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 " << colorOutputName << ";\n" 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_case == CASE_TRIANGLES) 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " vec3 weights = vec3(pow(gl_TessCoord.x, 1.3), pow(gl_TessCoord.y, 1.3), pow(gl_TessCoord.z, 1.3));\n" 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec3 cweights = gl_TessCoord;\n" 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(weights.x * gl_in[0].gl_Position.xyz + weights.y * gl_in[1].gl_Position.xyz + weights.z * gl_in[2].gl_Position.xyz, 1.0);\n" 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " << colorOutputName << " = cweights.x * v_patch_color[0] + cweights.y * v_patch_color[1] + cweights.z * v_patch_color[2];\n"; 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_QUADS || m_case == CASE_ISOLINES) 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " vec2 normalizedCoord = (gl_TessCoord.xy * 2.0 - vec2(1.0));\n" 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec2 normalizedWeights = normalizedCoord * (vec2(1.0) - 0.3 * cos(normalizedCoord.yx * 1.57));\n" 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec2 weights = normalizedWeights * 0.5 + vec2(0.5);\n" 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec2 cweights = gl_TessCoord.xy;\n" 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = mix(mix(gl_in[0].gl_Position, gl_in[1].gl_Position, weights.y), mix(gl_in[2].gl_Position, gl_in[3].gl_Position, weights.y), weights.x);\n" 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " " << colorOutputName << " = mix(mix(v_patch_color[0], v_patch_color[1], cweights.y), mix(v_patch_color[2], v_patch_color[3], cweights.y), cweights.x);\n"; 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityGeometryShaderCase::getGeometrySource (void) const 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryInputPrimitive = (m_case == CASE_ISOLINES) ? ("lines") : ("triangles"); 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryOutputPrimitive = (m_case == CASE_ISOLINES) ? ("line_strip") : ("triangle_strip"); 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numEmitVertices = (m_case == CASE_ISOLINES) ? (2) : (3); 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryInputPrimitive << ") in;\n" 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices <<") out;\n" 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_evaluated_color[];\n" 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_fragment_color;\n" 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < gl_in.length(); ++ndx)\n" 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position;\n" 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_fragment_color = v_evaluated_color[ndx];\n" 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n" 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass IdentityTessellationShaderCase : public IdentityShaderCase 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum CaseType 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASE_TRIANGLES = 0, 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry CASE_ISOLINES, 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IdentityTessellationShaderCase (Context& context, const char* name, const char* description, CaseType caseType); 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~IdentityTessellationShaderCase (void); 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationControlSource (void) const; 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationEvaluationSource (void) const; 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getGeometrySource (bool tessellationActive) const; 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 256, 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const CaseType m_case; 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_dataBuffer; 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityTessellationShaderCase::IdentityTessellationShaderCase (Context& context, const char* name, const char* description, CaseType caseType) 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : IdentityShaderCase (context, name, description) 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_case (caseType) 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_dataBuffer (0) 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityTessellationShaderCase::~IdentityTessellationShaderCase (void) 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IdentityTessellationShaderCase::init (void) 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Requirements 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderTarget().getHeight() < RENDER_SIZE) 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target."); 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Testing geometry shading shader program output does not change when a passthrough tessellation shader is attached.\n" 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Rendering two images, first with and second without a tessellation shader. Expecting similar results.\n" 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Using additive blending to detect overlap.\n" 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Resources 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const tcu::Vec4 pointData[] = 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f ), 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f ), 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.4f, 0.4f, 0.0f, 1.0f ), 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_dataBuffer); 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBuffer); 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, sizeof(pointData), pointData, GL_STATIC_DRAW); 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer"); 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid IdentityTessellationShaderCase::deinit (void) 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_dataBuffer) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_dataBuffer); 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_dataBuffer = 0; 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryIdentityTessellationShaderCase::IterateResult IdentityTessellationShaderCase::iterate (void) 5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resultWithTessellation (RENDER_SIZE, RENDER_SIZE); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resultWithoutTessellation (RENDER_SIZE, RENDER_SIZE); 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrimitiveVertices = (m_case == CASE_TRIANGLES) ? (3) : (2); 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const struct 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description; 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool containsTessellationShaders; 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::PixelBufferAccess surfaceAccess; 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } renderTargets[] = 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "RenderWithTessellationShader", "Render with tessellation shader", true, resultWithTessellation.getAccess() }, 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "RenderWithoutTessellationShader", "Render without tessellation shader", false, resultWithoutTessellation.getAccess() }, 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE); 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set viewport"); 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enable(GL_BLEND); 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendFunc(GL_SRC_ALPHA, GL_ONE); 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.blendEquation(GL_FUNC_ADD); 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set blend"); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // render with and without tessellation shader 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderTargets); ++renderNdx) 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::ScopedLogSection section (m_testCtx.getLog(), renderTargets[renderNdx].name, renderTargets[renderNdx].description); 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::VertexSource(getVertexSource()) 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()) 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::GeometrySource(getGeometrySource(renderTargets[renderNdx].containsTessellationShaders)); 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderTargets[renderNdx].containsTessellationShaders) 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TessellationControlSource(getTessellationControlSource()) 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource()); 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::ShaderProgram program (m_context.getRenderContext(), sources); 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int posLocation = gl.getAttribLocation(program.getProgram(), "a_position"); 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << program; 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!program.isOk()) 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (posLocation == -1) 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("a_position location was -1"); 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_dataBuffer); 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(posLocation); 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs"); 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(program.getProgram()); 5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (renderTargets[renderNdx].containsTessellationShaders) 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, numPrimitiveVertices); 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, numPrimitiveVertices); 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches"); 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays((m_case == CASE_TRIANGLES) ? (GL_TRIANGLES) : (GL_LINES), 0, numPrimitiveVertices); 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw primitives"); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, renderTargets[renderNdx].surfaceAccess); 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // compare 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool imageOk; 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getNumSamples() > 1) 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry imageOk = tcu::fuzzyCompare(m_testCtx.getLog(), 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "ImageCompare", 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Image comparison", 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithoutTessellation.getAccess(), 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithTessellation.getAccess(), 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.03f, 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_RESULT); 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry imageOk = tcu::intThresholdPositionDeviationCompare(m_testCtx.getLog(), 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "ImageCompare", 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Image comparison", 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithoutTessellation.getAccess(), 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultWithTessellation.getAccess(), 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec4(8, 8, 8, 255), //!< threshold 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec3(1, 1, 0), //!< 3x3 search kernel 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true, //!< fragments may end up over the viewport, just ignore them 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_RESULT); 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (imageOk) 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityTessellationShaderCase::getTessellationControlSource (void) const 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices = " << ((m_case == CASE_TRIANGLES) ? (3) : (2)) << ") out;\n" 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_vertex_color[];\n" 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_control_color[];\n" 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_control_color[gl_InvocationID] = v_vertex_color[gl_InvocationID];\n" 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n"; 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_case == CASE_TRIANGLES) 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = 1.0;\n" 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 1.0;\n" 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 1.0;\n" 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 1.0;\n"; 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_ISOLINES) 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = 1.0;\n" 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 1.0;\n"; 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityTessellationShaderCase::getTessellationEvaluationSource (void) const 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_case == CASE_TRIANGLES) ? ("triangles") : ("isolines")) 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ") in;\n" 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_control_color[];\n" 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_evaluated_color;\n" 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_case == CASE_TRIANGLES) 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n" 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_evaluated_color = gl_TessCoord.x * v_control_color[0] + gl_TessCoord.y * v_control_color[1] + gl_TessCoord.z * v_control_color[2];\n"; 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_ISOLINES) 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n" 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_evaluated_color = mix(v_control_color[0], v_control_color[1], gl_TessCoord.x);\n"; 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string IdentityTessellationShaderCase::getGeometrySource (bool tessellationActive) const 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const colorSourceName = (tessellationActive) ? ("v_evaluated_color") : ("v_vertex_color"); 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryInputPrimitive = (m_case == CASE_ISOLINES) ? ("lines") : ("triangles"); 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryOutputPrimitive = (m_case == CASE_ISOLINES) ? ("line_strip") : ("triangle_strip"); 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numEmitVertices = (m_case == CASE_ISOLINES) ? (11) : (8); 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryInputPrimitive << ") in;\n" 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices <<") out;\n" 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 " << colorSourceName << "[];\n" 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_fragment_color;\n" 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_case == CASE_TRIANGLES) 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " vec4 centerPos = (gl_in[0].gl_Position + gl_in[1].gl_Position + gl_in[2].gl_Position) / 3.0f;\n" 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < 4; ++ndx)\n" 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = centerPos + (centerPos - gl_in[ndx % 3].gl_Position);\n" 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_fragment_color = " << colorSourceName << "[ndx % 3];\n" 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = centerPos + 0.7 * (centerPos - gl_in[ndx % 3].gl_Position);\n" 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_fragment_color = " << colorSourceName << "[ndx % 3];\n" 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_case == CASE_ISOLINES) 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " vec4 mdir = vec4(gl_in[0].gl_Position.y - gl_in[1].gl_Position.y, gl_in[1].gl_Position.x - gl_in[0].gl_Position.x, 0.0, 0.0);\n" 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int i = 0; i <= 10; ++i)\n" 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float xweight = cos(float(i) / 10.0 * 6.28) * 0.5 + 0.5;\n" 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float mweight = sin(float(i) / 10.0 * 6.28) * 0.1 + 0.1;\n" 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, xweight) + mweight * mdir;\n" 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_fragment_color = mix(" << colorSourceName << "[0], " << colorSourceName << "[1], xweight);\n" 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FeedbackPrimitiveTypeCase : public TestCase 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum TessellationOutputType 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_OUT_TRIANGLES = 0, 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_OUT_QUADS, 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_OUT_ISOLINES, 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_OUT_LAST 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum TessellationPointMode 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_POINTMODE_OFF = 0, 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_POINTMODE_ON, 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TESSELLATION_POINTMODE_LAST 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum GeometryOutputType 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GEOMETRY_OUTPUT_POINTS = 0, 7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GEOMETRY_OUTPUT_LINES, 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GEOMETRY_OUTPUT_TRIANGLES, 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GEOMETRY_OUTPUT_LAST 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase (Context& context, 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name, 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description, 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationOutputType tessellationOutput, 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationPointMode tessellationPointMode, 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GeometryOutputType geometryOutputType); 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~FeedbackPrimitiveTypeCase (void); 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderWithFeedback (tcu::Surface& dst); 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderWithoutFeedback (tcu::Surface& dst); 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void verifyFeedbackResults (const std::vector<tcu::Vec4>& feedbackResult); 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void verifyRenderedImage (const tcu::Surface& image, const std::vector<tcu::Vec4>& vertices); 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void genTransformFeedback (void); 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getNumGeneratedElementsPerPrimitive (void) const; 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getNumGeneratedPrimitives (void) const; 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getNumTessellatedPrimitives (void) const; 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getGeometryAmplification (void) const; 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getVertexSource (void) const; 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getFragmentSource (void) const; 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationControlSource (void) const; 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationEvaluationSource (void) const; 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getGeometrySource (void) const; 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getTessellationOutputDescription (TessellationOutputType tessellationOutput, 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationPointMode tessellationPointMode); 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getGeometryInputDescription (TessellationOutputType tessellationOutput, 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationPointMode tessellationPointMode); 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const char* getGeometryOutputDescription (GeometryOutputType geometryOutput); 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum getOutputPrimitiveGLType (void) const; 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 128, 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessellationOutputType m_tessellationOutput; 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const TessellationPointMode m_tessellationPointMode; 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GeometryOutputType m_geometryOutputType; 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_feedbackProgram; 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_nonFeedbackProgram; 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_patchBuffer; 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_feedbackID; 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_feedbackBuffer; 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackPrimitiveTypeCase::FeedbackPrimitiveTypeCase (Context& context, 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name, 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description, 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationOutputType tessellationOutput, 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TessellationPointMode tessellationPointMode, 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GeometryOutputType geometryOutputType) 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_tessellationOutput (tessellationOutput) 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_tessellationPointMode (tessellationPointMode) 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_geometryOutputType (geometryOutputType) 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_feedbackProgram (DE_NULL) 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_nonFeedbackProgram (DE_NULL) 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_patchBuffer (0) 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_feedbackID (0) 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_feedbackBuffer (0) 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tessellationOutput < TESSELLATION_OUT_LAST); 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(tessellationPointMode < TESSELLATION_POINTMODE_LAST); 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(geometryOutputType < GEOMETRY_OUTPUT_LAST); 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackPrimitiveTypeCase::~FeedbackPrimitiveTypeCase (void) 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::init (void) 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Requirements 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderTarget().getHeight() < RENDER_SIZE) 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target."); 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Testing " 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << getTessellationOutputDescription(m_tessellationOutput, m_tessellationPointMode) 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "->" 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << getGeometryInputDescription(m_tessellationOutput, m_tessellationPointMode) 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " primitive conversion with and without transform feedback.\n" 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Sending a patch of 4 vertices (2x2 uniform grid) to tessellation control shader.\n" 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Control shader emits a patch of 9 vertices (3x3 uniform grid).\n" 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Setting outer tessellation level = 3, inner = 3.\n" 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Primitive generator emits " << getTessellationOutputDescription(m_tessellationOutput, m_tessellationPointMode) << "\n" 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Geometry shader transforms emitted primitives to " << getGeometryOutputDescription(m_geometryOutputType) << "\n" 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Reading back vertex positions of generated primitives using transform feedback.\n" 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Verifying rendered image and feedback vertices are consistent.\n" 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Rendering scene again with identical shader program, but without setting feedback varying. Expecting similar output image." 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Resources 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const tcu::Vec4 patchBufferData[4] = 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( -0.9f, -0.9f, 0.0f, 1.0f ), 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( -0.9f, 0.9f, 0.0f, 1.0f ), 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.9f, -0.9f, 0.0f, 1.0f ), 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4( 0.9f, 0.9f, 0.0f, 1.0f ), 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_patchBuffer); 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer); 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_ARRAY_BUFFER, sizeof(patchBufferData), patchBufferData, GL_STATIC_DRAW); 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen buffer"); 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_feedbackProgram = new glu::ShaderProgram(m_context.getRenderContext(), 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources() 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource(getVertexSource()) 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()) 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource(getTessellationControlSource()) 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource()) 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::GeometrySource(getGeometrySource()) 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying("tf_someVertexPosition") 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS)); 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_feedbackProgram; 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_feedbackProgram->isOk()) 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("failed to build program"); 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_nonFeedbackProgram = new glu::ShaderProgram(m_context.getRenderContext(), 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources() 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource(getVertexSource()) 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()) 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource(getTessellationControlSource()) 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource()) 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::GeometrySource(getGeometrySource())); 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_nonFeedbackProgram->isOk()) 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_nonFeedbackProgram; 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("failed to build program"); 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry genTransformFeedback(); 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::deinit (void) 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_patchBuffer) 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_patchBuffer); 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_patchBuffer = 0; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_feedbackBuffer) 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_feedbackBuffer); 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_feedbackBuffer = 0; 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_feedbackID) 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteTransformFeedbacks(1, &m_feedbackID); 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_feedbackID = 0; 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_feedbackProgram) 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_feedbackProgram; 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_feedbackProgram = DE_NULL; 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_nonFeedbackProgram) 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_nonFeedbackProgram; 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_nonFeedbackProgram = DE_NULL; 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackPrimitiveTypeCase::IterateResult FeedbackPrimitiveTypeCase::iterate (void) 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface feedbackResult (RENDER_SIZE, RENDER_SIZE); 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface nonFeedbackResult (RENDER_SIZE, RENDER_SIZE); 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // render with and without XFB 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderWithFeedback(feedbackResult); 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderWithoutFeedback(nonFeedbackResult); 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // compare 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool imageOk; 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Comparing the image rendered with no transform feedback against the image rendered with enabled transform feedback." << tcu::TestLog::EndMessage; 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getNumSamples() > 1) 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry imageOk = tcu::fuzzyCompare(m_testCtx.getLog(), 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "ImageCompare", 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Image comparison", 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry feedbackResult.getAccess(), 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nonFeedbackResult.getAccess(), 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 0.03f, 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_RESULT); 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry imageOk = tcu::intThresholdPositionDeviationCompare(m_testCtx.getLog(), 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "ImageCompare", 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Image comparison", 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry feedbackResult.getAccess(), 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry nonFeedbackResult.getAccess(), 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec4(8, 8, 8, 255), //!< threshold 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec3(1, 1, 0), //!< 3x3 search kernel 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true, //!< fragments may end up over the viewport, just ignore them 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::COMPARE_LOG_RESULT); 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!imageOk) 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed"); 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::renderWithFeedback(tcu::Surface& dst) 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::Query primitivesGeneratedQuery (m_context.getRenderContext()); 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int posLocation = gl.getAttribLocation(m_feedbackProgram->getProgram(), "a_position"); 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::GLenum feedbackPrimitiveMode = getOutputPrimitiveGLType(); 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (posLocation == -1) 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("a_position was -1"); 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering with transform feedback" << tcu::TestLog::EndMessage; 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, dst.getWidth(), dst.getHeight()); 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer); 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(posLocation); 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs"); 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_feedbackProgram->getProgram()); 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 4); 10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.beginQuery(GL_PRIMITIVES_GENERATED, *primitivesGeneratedQuery); 10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "begin GL_PRIMITIVES_GENERATED query"); 10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Begin transform feedback with mode " << glu::getPrimitiveTypeStr(feedbackPrimitiveMode) << tcu::TestLog::EndMessage; 10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.beginTransformFeedback(feedbackPrimitiveMode); 10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "begin xfb"); 10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Calling drawArrays with mode GL_PATCHES" << tcu::TestLog::EndMessage; 10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 4); 10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches"); 10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.endTransformFeedback(); 10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "end xfb"); 10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.endQuery(GL_PRIMITIVES_GENERATED); 10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "end GL_PRIMITIVES_GENERATED query"); 10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess()); 10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels"); 10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify GL_PRIMITIVES_GENERATED 10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLuint primitivesGeneratedResult = 0; 10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getQueryObjectuiv(*primitivesGeneratedQuery, GL_QUERY_RESULT, &primitivesGeneratedResult); 10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_PRIMITIVES_GENERATED value"); 10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying GL_PRIMITIVES_GENERATED, expecting " << getNumGeneratedPrimitives() << tcu::TestLog::EndMessage; 10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((int)primitivesGeneratedResult != getNumGeneratedPrimitives()) 10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Error, GL_PRIMITIVES_GENERATED was " << primitivesGeneratedResult << tcu::TestLog::EndMessage; 10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unexpected GL_PRIMITIVES_GENERATED"); 10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "GL_PRIMITIVES_GENERATED valid." << tcu::TestLog::EndMessage; 10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // feedback 10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<tcu::Vec4> feedbackResults (getNumGeneratedElementsPerPrimitive() * getNumGeneratedPrimitives()); 10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* mappedPtr = gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, (glw::GLsizeiptr)(feedbackResults.size() * sizeof(tcu::Vec4)), GL_MAP_READ_BIT); 10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLboolean unmapResult; 10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "mapBufferRange"); 10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Reading transform feedback buffer." << tcu::TestLog::EndMessage; 10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!mappedPtr) 10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("mapBufferRange returned null"); 10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(feedbackResults[0].getPtr(), mappedPtr, (int)(feedbackResults.size() * sizeof(tcu::Vec4))); 10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry unmapResult = gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "unmapBuffer"); 10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (unmapResult != GL_TRUE) 10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("unmapBuffer failed, did not return true"); 10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify transform results 10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry verifyFeedbackResults(feedbackResults); 10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify feedback results are consistent with rendered image 10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry verifyRenderedImage(dst, feedbackResults); 10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::renderWithoutFeedback (tcu::Surface& dst) 10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int posLocation = gl.getAttribLocation(m_nonFeedbackProgram->getProgram(), "a_position"); 11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (posLocation == -1) 11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("a_position was -1"); 11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering without transform feedback" << tcu::TestLog::EndMessage; 11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, dst.getWidth(), dst.getHeight()); 11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_ARRAY_BUFFER, m_patchBuffer); 11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttribPointer(posLocation, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); 11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.enableVertexAttribArray(posLocation); 11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "setup attribs"); 11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_nonFeedbackProgram->getProgram()); 11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 4); 11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Calling drawArrays with mode GL_PATCHES" << tcu::TestLog::EndMessage; 11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 4); 11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches"); 11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess()); 11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "readPixels"); 11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::verifyFeedbackResults (const std::vector<tcu::Vec4>& feedbackResult) 11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int geometryAmplification = getGeometryAmplification(); 11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elementsPerPrimitive = getNumGeneratedElementsPerPrimitive(); 11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int errorFloodThreshold = 8; 11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int readNdx = 0; 11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numErrors = 0; 11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying feedback results." << tcu::TestLog::EndMessage; 11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int tessellatedPrimitiveNdx = 0; tessellatedPrimitiveNdx < getNumTessellatedPrimitives(); ++tessellatedPrimitiveNdx) 11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 primitiveVertex = feedbackResult[readNdx]; 11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check the generated vertices are in the proper range (range: -0.4 <-> 0.4) 11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float equalThreshold = 1.0e-6f; 11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool centroidOk = (primitiveVertex.x() >= -0.4f - equalThreshold) && 11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (primitiveVertex.x() <= 0.4f + equalThreshold) && 11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (primitiveVertex.y() >= -0.4f - equalThreshold) && 11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (primitiveVertex.y() <= 0.4f + equalThreshold) && 11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (de::abs(primitiveVertex.z()) < equalThreshold) && 11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (de::abs(primitiveVertex.w() - 1.0f) < equalThreshold); 11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!centroidOk && numErrors++ < errorFloodThreshold) 11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Element at index " << (readNdx) << " (tessellation invocation " << tessellatedPrimitiveNdx << ")\n" 11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\texpected vertex in range: ( [-0.4, 0.4], [-0.4, 0.4], 0.0, 1.0 )\n" 11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tgot: " << primitiveVertex 11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid feedback output"); 11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ++readNdx; 11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry continue; 11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // check all other primitives generated from this tessellated primitive have the same feedback value 11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int generatedPrimitiveNdx = 0; generatedPrimitiveNdx < geometryAmplification; ++generatedPrimitiveNdx) 11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int primitiveVertexNdx = 0; primitiveVertexNdx < elementsPerPrimitive; ++primitiveVertexNdx) 11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 generatedElementVertex = feedbackResult[readNdx]; 11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::Vec4 equalThreshold (1.0e-6f); 11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tcu::boolAny(tcu::greaterThan(tcu::abs(primitiveVertex - generatedElementVertex), equalThreshold))) 11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrors++ < errorFloodThreshold) 11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Element at index " << (readNdx) << " (tessellation invocation " << tessellatedPrimitiveNdx << ", geometry primitive " << generatedPrimitiveNdx << ", emitted vertex " << primitiveVertexNdx << "):\n" 11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tfeedback result was not contant over whole primitive.\n" 11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tfirst emitted value: " << primitiveVertex << "\n" 11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tcurrent emitted value:" << generatedElementVertex << "\n" 11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got multiple different feedback values for a single primitive"); 11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry readNdx++; 11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (numErrors > errorFloodThreshold) 12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (numErrors - errorFloodThreshold) << " error(s)." << tcu::TestLog::EndMessage; 12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool feedbackResultCompare (const tcu::Vec4& a, const tcu::Vec4& b) 12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.x() < b.x()) 12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (a.x() > b.x()) 12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return a.y() < b.y(); 12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::verifyRenderedImage (const tcu::Surface& image, const std::vector<tcu::Vec4>& tfVertices) 12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<tcu::Vec4> vertices; 12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Comparing result image against feedback results." << tcu::TestLog::EndMessage; 12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check only unique vertices 12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::unique_copy(tfVertices.begin(), tfVertices.end(), std::back_insert_iterator<std::vector<tcu::Vec4> >(vertices)); 12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::sort(vertices.begin(), vertices.end(), feedbackResultCompare); 12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertices.erase(std::unique(vertices.begin(), vertices.end()), vertices.end()); 12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verifying vertices recorded with feedback actually ended up on the result image 12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)vertices.size(); ++ndx) 12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Rasterization (of lines) may deviate by one pixel. In addition to that, allow minimal errors in rasterized position vs. feedback result. 12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // This minimal error could result in a difference in rounding => allow one additional pixel in deviation 12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int rasterDeviation = 2; 12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec2 rasterPos ((int)deFloatRound((vertices[ndx].x() * 0.5f + 0.5f) * image.getWidth()), (int)deFloatRound((vertices[ndx].y() * 0.5f + 0.5f) * image.getHeight())); 12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find produced rasterization results 12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool found = false; 12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dy = -rasterDeviation; dy <= rasterDeviation && !found; ++dy) 12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int dx = -rasterDeviation; dx <= rasterDeviation && !found; ++dx) 12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Raster result could end up outside the viewport 12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (rasterPos.x() + dx < 0 || rasterPos.x() + dx >= image.getWidth() || 12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry rasterPos.y() + dy < 0 || rasterPos.y() + dy >= image.getHeight()) 12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry found = true; 12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::RGBA result = image.getPixel(rasterPos.x() + dx, rasterPos.y() + dy); 12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if(!isBlack(result)) 12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry found = true; 12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!found) 12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Vertex " << vertices[ndx] << "\n" 12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tCould not find rasterization output for vertex.\n" 12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tExpected non-black pixels near " << rasterPos 12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "invalid result image"); 12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackPrimitiveTypeCase::genTransformFeedback (void) 12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int elementsPerPrimitive = getNumGeneratedElementsPerPrimitive(); 12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int feedbackPrimitives = getNumGeneratedPrimitives(); 12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int feedbackElements = elementsPerPrimitive * feedbackPrimitives; 12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::vector<tcu::Vec4> initialBuffer (feedbackElements, tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f)); 12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genTransformFeedbacks(1, &m_feedbackID); 12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_feedbackID); 12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen transform feedback"); 12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_feedbackBuffer); 12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_feedbackBuffer); 12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(tcu::Vec4) * initialBuffer.size(), initialBuffer[0].getPtr(), GL_STATIC_COPY); 12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen feedback buffer"); 12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_feedbackBuffer); 12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind feedback buffer"); 12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getTriangleNumOutputPrimitives (int tessellationLevel) 12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tessellationLevel == 1) 12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (tessellationLevel == 2) 12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 6; 12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 3 * (2 + 2 * (tessellationLevel - 2)) + getTriangleNumOutputPrimitives(tessellationLevel - 2); 12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getTriangleNumOutputPrimitivesPoints (int tessellationLevel) 13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tessellationLevel == 0) 13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (tessellationLevel == 1) 13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 3; 13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 3 + 3 * (tessellationLevel - 1) + getTriangleNumOutputPrimitivesPoints(tessellationLevel - 2); 13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint FeedbackPrimitiveTypeCase::getNumGeneratedElementsPerPrimitive (void) const 13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_geometryOutputType == GEOMETRY_OUTPUT_TRIANGLES) 13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 3; 13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) 13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 2; 13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) 13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint FeedbackPrimitiveTypeCase::getNumGeneratedPrimitives (void) const 13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getNumTessellatedPrimitives() * getGeometryAmplification(); 13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint FeedbackPrimitiveTypeCase::getNumTessellatedPrimitives (void) const 13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int tessellationLevel = 3; 13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_tessellationPointMode == TESSELLATION_POINTMODE_OFF) 13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) 13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getTriangleNumOutputPrimitives(tessellationLevel); 13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_QUADS) 13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessellationLevel * tessellationLevel * 2; // tessellated as triangles 13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) 13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessellationLevel * tessellationLevel; 13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationPointMode == TESSELLATION_POINTMODE_ON) 13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) 13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return getTriangleNumOutputPrimitivesPoints(tessellationLevel); 13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_QUADS) 13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (tessellationLevel + 1) * (tessellationLevel + 1); 13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) 13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return tessellationLevel * (tessellationLevel + 1); 13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint FeedbackPrimitiveTypeCase::getGeometryAmplification (void) const 13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int outputAmplification = (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? (2) : (1); 13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInputVertices = (m_tessellationPointMode) ? (1) : (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? (2) : (3); 13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return outputAmplification * numInputVertices; 13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryglw::GLenum FeedbackPrimitiveTypeCase::getOutputPrimitiveGLType (void) const 13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_geometryOutputType == GEOMETRY_OUTPUT_TRIANGLES) 13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GL_TRIANGLES; 13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) 13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GL_LINES; 13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) 13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return GL_POINTS; 13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackPrimitiveTypeCase::getVertexSource (void) const 13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_positionVertexShader; 13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackPrimitiveTypeCase::getFragmentSource (void) const 13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_whiteOutputFragmentShader; 13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string FeedbackPrimitiveTypeCase::getTessellationControlSource (void) const 13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices = 9) out;\n" 13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform highp float u_innerTessellationLevel;\n" 13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "uniform highp float u_outerTessellationLevel;\n" 14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (gl_PatchVerticesIn != 4)\n" 14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " return;\n" 14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Convert input 2x2 grid to 3x3 grid\n" 14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float xweight = float(gl_InvocationID % 3) / 2.0f;\n" 14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float yweight = float(gl_InvocationID / 3) / 2.0f;\n" 14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 y0 = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, yweight);\n" 14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 y1 = mix(gl_in[2].gl_Position, gl_in[3].gl_Position, yweight);\n" 14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = mix(y0, y1, xweight);\n" 14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n"; 14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) 14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = 3.0;\n" 14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 3.0;\n" 14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 3.0;\n" 14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 3.0;\n"; 14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_QUADS) 14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = 3.0;\n" 14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 3.0;\n" 14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 3.0;\n" 14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = 3.0;\n" 14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 3.0;\n" 14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = 3.0;\n"; 14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) 14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_TessLevelOuter[0] = 3.0;\n" 14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 3.0;\n"; 14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string FeedbackPrimitiveTypeCase::getTessellationEvaluationSource (void) const 14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" 14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) ? ("triangles") : (m_tessellationOutput == TESSELLATION_OUT_QUADS) ? ("quads") : ("isolines")) 14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_tessellationPointMode) ? (", point_mode") : ("")) 14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ") in;\n" 14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 v_tessellationCoords;\n" 14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (gl_PatchVerticesIn != 9)\n" 14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " return;\n" 14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 patchCentroid = vec4(0.0);\n" 14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < gl_PatchVerticesIn; ++ndx)\n" 14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " patchCentroid += gl_in[ndx].gl_Position;\n" 14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " patchCentroid /= patchCentroid.w;\n" 14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n"; 14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_tessellationOutput == TESSELLATION_OUT_TRIANGLES) 14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // map barycentric coords to 2d coords\n" 14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const vec3 tessDirX = vec3( 0.4, 0.4, 0.0);\n" 14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const vec3 tessDirY = vec3( 0.0, -0.4, 0.0);\n" 14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const vec3 tessDirZ = vec3(-0.4, 0.4, 0.0);\n" 14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = patchCentroid + vec4(gl_TessCoord.x * tessDirX + gl_TessCoord.y * tessDirY + gl_TessCoord.z * tessDirZ, 0.0);\n"; 14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_tessellationOutput == TESSELLATION_OUT_QUADS || m_tessellationOutput == TESSELLATION_OUT_ISOLINES) 14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = patchCentroid + vec4(gl_TessCoord.x * 0.8 - 0.4, gl_TessCoord.y * 0.8 - 0.4, 0.0, 0.0);\n"; 14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " v_tessellationCoords = vec4(gl_TessCoord, 0.0);\n" 14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string FeedbackPrimitiveTypeCase::getGeometrySource (void) const 14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryInputPrimitive = (m_tessellationPointMode) ? ("points") : (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? ("lines") : ("triangles"); 14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* const geometryOutputPrimitive = (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) ? ("points") : (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? ("line_strip") : ("triangle_strip"); 14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numInputVertices = (m_tessellationPointMode) ? (1) : (m_tessellationOutput == TESSELLATION_OUT_ISOLINES) ? (2) : (3); 14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSingleVertexOutputVertices = (m_geometryOutputType == GEOMETRY_OUTPUT_POINTS) ? (1) : (m_geometryOutputType == GEOMETRY_OUTPUT_LINES) ? (4) : (3); 14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numEmitVertices = numInputVertices * numSingleVertexOutputVertices; 14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryInputPrimitive << ") in;\n" 14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(" << geometryOutputPrimitive << ", max_vertices=" << numEmitVertices <<") out;\n" 14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 v_tessellationCoords[];\n" 14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 tf_someVertexPosition;\n" 14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Emit primitive\n" 15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < gl_in.length(); ++ndx)\n" 15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n"; 15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (m_geometryOutputType) 15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_POINTS: 15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Draw point on vertex\n" 15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position;\n" 15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n"; 15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_LINES: 15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Draw cross on vertex\n" 15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4(-0.02, -0.02, 0.0, 0.0);\n" 15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, 0.02, 0.0, 0.0);\n" 15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n" 15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, -0.02, 0.0, 0.0);\n" 15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4(-0.02, 0.02, 0.0, 0.0);\n" 15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n"; 15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_TRIANGLES: 15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Draw triangle on vertex\n" 15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4( 0.00, -0.02, 0.0, 0.0);\n" 15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4( 0.02, 0.00, 0.0, 0.0);\n" 15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4( -0.02, 0.00, 0.0, 0.0);\n" 15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_someVertexPosition = gl_in[gl_in.length() - 1].gl_Position;\n" 15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n"; 15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ""; 15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " }\n" 15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackPrimitiveTypeCase::getTessellationOutputDescription (TessellationOutputType tessellationOutput, TessellationPointMode pointMode) 15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (tessellationOutput) 15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_TRIANGLES: return (pointMode) ? ("points (triangles in point mode)") : ("triangles"); 15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_QUADS: return (pointMode) ? ("points (quads in point mode)") : ("quads"); 15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_ISOLINES: return (pointMode) ? ("points (isolines in point mode)") : ("isolines"); 15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackPrimitiveTypeCase::getGeometryInputDescription (TessellationOutputType tessellationOutput, TessellationPointMode pointMode) 15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (tessellationOutput) 15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_TRIANGLES: return (pointMode) ? ("points") : ("triangles"); 15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_QUADS: return (pointMode) ? ("points") : ("triangles"); 15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case TESSELLATION_OUT_ISOLINES: return (pointMode) ? ("points") : ("lines"); 15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackPrimitiveTypeCase::getGeometryOutputDescription (GeometryOutputType geometryOutput) 15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry switch (geometryOutput) 15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_POINTS: return "points"; 15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_LINES: return "lines"; 15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry case GEOMETRY_OUTPUT_TRIANGLES: return "triangles"; 15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry default: 15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PointSizeCase : public TestCase 15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum Flags 15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_VERTEX_SET = 0x01, // !< set gl_PointSize in vertex shader 16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_CONTROL_SET = 0x02, // !< set gl_PointSize in tessellation evaluation shader 16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_EVALUATION_SET = 0x04, // !< set gl_PointSize in tessellation control shader 16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_ADD = 0x08, // !< read and add to gl_PointSize in tessellation shader pair 16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_DONT_SET = 0x10, // !< don't set gl_PointSize in tessellation shader 16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_SET = 0x20, // !< set gl_PointSize in geometry shader 16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_ADD = 0x40, // !< read and add to gl_PointSize in geometry shader 16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_DONT_SET = 0x80, // !< don't set gl_PointSize in geometry shader 16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase (Context& context, const char* name, const char* description, int flags); 16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~PointSizeCase (void); 16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static std::string genTestCaseName (int flags); 16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static std::string genTestCaseDescription (int flags); 16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void checkExtensions (void) const; 16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void checkPointSizeRequirements (void) const; 16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTo (tcu::Surface& dst); 16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verifyImage (const tcu::Surface& src); 16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int getExpectedPointSize (void) const; 16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genVertexSource (void) const; 16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* genFragmentSource (void) const; 16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genTessellationControlSource (void) const; 16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genTessellationEvaluationSource (void) const; 16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string genGeometrySource (void) const; 16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 32, 16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_flags; 16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPointSizeCase::PointSizeCase (Context& context, const char* name, const char* description, int flags) 16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_flags (flags) 16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPointSizeCase::~PointSizeCase (void) 16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genTestCaseName (int flags) 16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // join per-bit descriptions into a single string with '_' separator 16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_VERTEX_SET) buf << "vertex_set"; 16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_CONTROL_SET) buf << ((flags & (FLAG_TESSELLATION_CONTROL_SET-1)) ? ("_") : ("")) << "control_set"; 16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_EVALUATION_SET) buf << ((flags & (FLAG_TESSELLATION_EVALUATION_SET-1)) ? ("_") : ("")) << "evaluation_set"; 16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_ADD) buf << ((flags & (FLAG_TESSELLATION_ADD-1)) ? ("_") : ("")) << "control_pass_eval_add"; 16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_DONT_SET) buf << ((flags & (FLAG_TESSELLATION_DONT_SET-1)) ? ("_") : ("")) << "eval_default"; 16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_SET) buf << ((flags & (FLAG_GEOMETRY_SET-1)) ? ("_") : ("")) << "geometry_set"; 16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_ADD) buf << ((flags & (FLAG_GEOMETRY_ADD-1)) ? ("_") : ("")) << "geometry_add"; 16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_DONT_SET) buf << ((flags & (FLAG_GEOMETRY_DONT_SET-1)) ? ("_") : ("")) << "geometry_default"; 16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genTestCaseDescription (int flags) 16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // join per-bit descriptions into a single string with ", " separator 16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_VERTEX_SET) buf << "set point size in vertex shader"; 16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_CONTROL_SET) buf << ((flags & (FLAG_TESSELLATION_CONTROL_SET-1)) ? (", ") : ("")) << "set point size in tessellation control shader"; 16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_EVALUATION_SET) buf << ((flags & (FLAG_TESSELLATION_EVALUATION_SET-1)) ? (", ") : ("")) << "set point size in tessellation evaluation shader"; 16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_ADD) buf << ((flags & (FLAG_TESSELLATION_ADD-1)) ? (", ") : ("")) << "add to point size in tessellation shader"; 16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_TESSELLATION_DONT_SET) buf << ((flags & (FLAG_TESSELLATION_DONT_SET-1)) ? (", ") : ("")) << "don't set point size in tessellation evaluation shader"; 16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_SET) buf << ((flags & (FLAG_GEOMETRY_SET-1)) ? (", ") : ("")) << "set point size in geometry shader"; 16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_ADD) buf << ((flags & (FLAG_GEOMETRY_ADD-1)) ? (", ") : ("")) << "add to point size in geometry shader"; 16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (flags & FLAG_GEOMETRY_DONT_SET) buf << ((flags & (FLAG_GEOMETRY_DONT_SET-1)) ? (", ") : ("")) << "don't set point size in geometry shader"; 16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PointSizeCase::init (void) 16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkExtensions(); 16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry checkPointSizeRequirements(); 16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // log 16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_VERTEX_SET) 16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in vertex shader to 2.0." << tcu::TestLog::EndMessage; 16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_CONTROL_SET) 16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in tessellation control shader to 4.0. (And ignoring it in evaluation)." << tcu::TestLog::EndMessage; 16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_EVALUATION_SET) 17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in tessellation evaluation shader to 4.0." << tcu::TestLog::EndMessage; 17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_ADD) 17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Reading point size in tessellation control shader and adding 2.0 to it in evaluation." << tcu::TestLog::EndMessage; 17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_DONT_SET) 17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Not setting point size in tessellation evaluation shader (resulting in the default point size)." << tcu::TestLog::EndMessage; 17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SET) 17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Setting point size in geometry shader to 6.0." << tcu::TestLog::EndMessage; 17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_ADD) 17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Reading point size in geometry shader and adding 2.0." << tcu::TestLog::EndMessage; 17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_DONT_SET) 17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Not setting point size in geometry shader (resulting in the default point size)." << tcu::TestLog::EndMessage; 17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // program 17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::VertexSource(genVertexSource()) 17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(genFragmentSource()); 17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD | FLAG_TESSELLATION_DONT_SET)) 17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TessellationControlSource(genTessellationControlSource()) 17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(genTessellationEvaluationSource()); 17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD | FLAG_GEOMETRY_DONT_SET)) 17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::GeometrySource(genGeometrySource()); 17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources); 17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("failed to build program"); 17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PointSizeCase::deinit (void) 17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPointSizeCase::IterateResult PointSizeCase::iterate (void) 17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface resultImage(RENDER_SIZE, RENDER_SIZE); 17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTo(resultImage); 17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (verifyImage(resultImage)) 17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PointSizeCase::checkExtensions (void) const 17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<std::string> requiredExtensions; 17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allOk = true; 17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD | FLAG_TESSELLATION_DONT_SET)) 17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry requiredExtensions.push_back("GL_EXT_tessellation_shader"); 17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD)) 17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry requiredExtensions.push_back("GL_EXT_tessellation_point_size"); 17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD | FLAG_GEOMETRY_DONT_SET))) 17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry requiredExtensions.push_back("GL_EXT_geometry_shader"); 17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (m_flags & (FLAG_GEOMETRY_SET | FLAG_GEOMETRY_ADD))) 17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry requiredExtensions.push_back("GL_EXT_geometry_point_size"); 17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)requiredExtensions.size(); ++ndx) 17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported(requiredExtensions[ndx].c_str())) 17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allOk = false; 17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!allOk) 17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream extensionList; 17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < (int)requiredExtensions.size(); ++ndx) 17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ndx != 0) 17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry extensionList << ", "; 17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry extensionList << requiredExtensions[ndx]; 17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires {" + extensionList.str() + "} extension(s)"); 17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PointSizeCase::checkPointSizeRequirements (void) const 17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float aliasedSizeRange[2] = { 0.0f, 0.0f }; 17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int requiredSize = getExpectedPointSize(); 17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getFloatv(GL_ALIASED_POINT_SIZE_RANGE, aliasedSizeRange); 17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (float(requiredSize) > aliasedSizeRange[1]) 17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires point size " + de::toString(requiredSize)); 18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PointSizeCase::renderTo (tcu::Surface& dst) 18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool tessellationActive = (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_EVALUATION_SET | FLAG_TESSELLATION_ADD | FLAG_TESSELLATION_DONT_SET)) != 0; 18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position"); 18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering single point." << tcu::TestLog::EndMessage; 18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (positionLocation == -1) 18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Attribute a_position location was -1"); 18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE); 18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao"); 18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f); 18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (tessellationActive) 18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 1); 18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw patches"); 18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_POINTS, 0, 1); 18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "draw points"); 18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst.getAccess()); 18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool PointSizeCase::verifyImage (const tcu::Surface& src) 18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool MSAATarget = (m_context.getRenderTarget().getNumSamples() > 1); 18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int expectedSize = getExpectedPointSize(); 18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying rendered point size. Expecting " << expectedSize << " pixels." << tcu::TestLog::EndMessage; 18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Image("RenderImage", "Rendered image", src.getAccess()); 18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool resultAreaFound = false; 18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec4 resultArea; 18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Find rasterization output area 18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < src.getHeight(); ++y) 18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < src.getWidth(); ++x) 18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isBlack(src.getPixel(x, y))) 18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!resultAreaFound) 18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // first fragment 18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultArea = tcu::IVec4(x, y, x + 1, y + 1); 18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultAreaFound = true; 18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // union area 18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultArea.x() = de::min(resultArea.x(), x); 18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultArea.y() = de::min(resultArea.y(), y); 18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultArea.z() = de::max(resultArea.z(), x+1); 18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry resultArea.w() = de::max(resultArea.w(), y+1); 18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!resultAreaFound) 18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verification failed, could not find any point fragments." << tcu::TestLog::EndMessage; 18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // verify area size 18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (MSAATarget) 18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec2 pointSize = resultArea.swizzle(2,3) - resultArea.swizzle(0, 1); 18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // MSAA: edges may be a little fuzzy 18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (de::abs(pointSize.x() - pointSize.y()) > 1) 18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Rasterized point is not a square. Detected point size was " << pointSize << tcu::TestLog::EndMessage; 18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // MSAA may produce larger areas, allow one pixel larger 18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (expectedSize != de::max(pointSize.x(), pointSize.y()) && (expectedSize+1) != de::max(pointSize.x(), pointSize.y())) 19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Point size invalid, expected " << expectedSize << ", got " << de::max(pointSize.x(), pointSize.y()) << tcu::TestLog::EndMessage; 19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::IVec2 pointSize = resultArea.swizzle(2,3) - resultArea.swizzle(0, 1); 19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pointSize.x() != pointSize.y()) 19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Rasterized point is not a square. Point size was " << pointSize << tcu::TestLog::EndMessage; 19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pointSize.x() != expectedSize) 19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "ERROR! Point size invalid, expected " << expectedSize << ", got " << pointSize.x() << tcu::TestLog::EndMessage; 19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint PointSizeCase::getExpectedPointSize (void) const 19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int addition = 0; 19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // geometry 19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_DONT_SET) 19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_SET) 19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 6; 19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_ADD) 19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addition += 2; 19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tessellation 19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_EVALUATION_SET) 19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 4 + addition; 19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_TESSELLATION_ADD) 19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addition += 2; 19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & (FLAG_TESSELLATION_CONTROL_SET | FLAG_TESSELLATION_DONT_SET)) 19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT((m_flags & FLAG_GEOMETRY_ADD) == 0); // reading pointSize undefined 19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 1; 19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // vertex 19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_VERTEX_SET) 19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return 2 + addition; 19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // undefined 19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(false); 19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return -1; 19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genVertexSource (void) const 19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in highp vec4 a_position;\n" 19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_Position = a_position;\n"; 19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_VERTEX_SET) 19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_PointSize = 2.0;\n"; 19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* PointSizeCase::genFragmentSource (void) const 19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_whiteOutputFragmentShader; 19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genTessellationControlSource (void) const 19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "#extension GL_EXT_tessellation_shader : require\n" 19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_flags & FLAG_TESSELLATION_DONT_SET) ? ("") : ("#extension GL_EXT_tessellation_point_size : require\n")) 19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(vertices = 1) out;\n" 19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_TessLevelOuter[0] = 3.0;\n" 19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_TessLevelOuter[1] = 3.0;\n" 19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_TessLevelOuter[2] = 3.0;\n" 19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_TessLevelInner[0] = 3.0;\n" 19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"; 19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_ADD) 19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // pass as is to eval\n" 19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"; 20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_TESSELLATION_CONTROL_SET) 20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // thrown away\n" 20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_out[gl_InvocationID].gl_PointSize = 4.0;\n"; 20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genTessellationEvaluationSource (void) const 20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "#extension GL_EXT_tessellation_shader : require\n" 20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_flags & FLAG_TESSELLATION_DONT_SET) ? ("") : ("#extension GL_EXT_tessellation_point_size : require\n")) 20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(triangles, point_mode) in;\n" 20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n" 20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " // hide all but one vertex\n" 20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " if (gl_TessCoord.x < 0.99)\n" 20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_Position = vec4(-2.0, 0.0, 0.0, 1.0);\n" 20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " else\n" 20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_Position = gl_in[0].gl_Position;\n"; 20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_ADD) 20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " // add to point size\n" 20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_PointSize = gl_in[0].gl_PointSize + 2.0;\n"; 20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_TESSELLATION_EVALUATION_SET) 20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " // set point size\n" 20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_PointSize = 4.0;\n"; 20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string PointSizeCase::genGeometrySource (void) const 20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "#extension GL_EXT_geometry_shader : require\n" 20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ((m_flags & FLAG_GEOMETRY_DONT_SET) ? ("") : ("#extension GL_EXT_geometry_point_size : require\n")) 20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (points) in;\n" 20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout (points, max_vertices=1) out;\n" 20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\n" 20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "void main ()\n" 20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "{\n"; 20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SET) 20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = gl_in[0].gl_Position;\n" 20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_PointSize = 6.0;\n"; 20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_ADD) 20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = gl_in[0].gl_Position;\n" 20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_PointSize = gl_in[0].gl_PointSize + 2.0;\n"; 20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_DONT_SET) 20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " gl_Position = gl_in[0].gl_Position;\n"; 20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " EmitVertex();\n" 20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "}\n"; 20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass AllowedRenderFailureException : public std::runtime_error 20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry AllowedRenderFailureException (const char* message) : std::runtime_error(message) { } 20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GridRenderCase : public TestCase 20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum Flags 20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_MAX_SPEC = 0x0001, 20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_TESSELLATION_MAX_IMPLEMENTATION = 0x0002, 20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_MAX_SPEC = 0x0004, 20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_MAX_IMPLEMENTATION = 0x0008, 20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC = 0x0010, 20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION = 0x0020, 20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_SCATTER_INSTANCES = 0x0040, 20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_SCATTER_PRIMITIVES = 0x0080, 20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_SEPARATE_PRIMITIVES = 0x0100, //!< if set, geometry shader outputs separate grid cells and not continuous slices 20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_GEOMETRY_SCATTER_LAYERS = 0x0200, 20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FLAG_ALLOW_OUT_OF_MEMORY = 0x0400, //!< allow draw command to set GL_OUT_OF_MEMORY 20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase (Context& context, const char* name, const char* description, int flags); 20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~GridRenderCase (void); 20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void renderTo (std::vector<tcu::Surface>& dst); 21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool verifyResultLayer (int layerNdx, const tcu::Surface& dst); 21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getVertexSource (void); 21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getFragmentSource (void); 21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationControlSource (int tessLevel); 21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getTessellationEvaluationSource (int tessLevel); 21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string getGeometryShaderSource (int numPrimitives, int numInstances, int tessLevel); 21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry enum 21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry RENDER_SIZE = 256 21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int m_flags; 21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_texture; 21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numLayers; 21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::GridRenderCase (Context& context, const char* name, const char* description, int flags) 21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_flags (flags) 21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_texture (0) 21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numLayers (1) 21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_TESSELLATION_MAX_SPEC) == 0) || ((m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) == 0)); 21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_GEOMETRY_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) == 0)); 21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) == 0) || ((m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) == 0)); 21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(((m_flags & (FLAG_GEOMETRY_SCATTER_PRIMITIVES | FLAG_GEOMETRY_SCATTER_LAYERS)) != 0) == ((m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) != 0)); 21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::~GridRenderCase (void) 21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::init (void) 21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Requirements 21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if ((m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) == 0) 21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_context.getRenderTarget().getWidth() < RENDER_SIZE || 21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderTarget().getHeight() < RENDER_SIZE) 21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires " + de::toString<int>(RENDER_SIZE) + "x" + de::toString<int>(RENDER_SIZE) + " or larger render target."); 21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Log 21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Testing tessellation and geometry shaders that output a large number of primitives.\n" 21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << getDescription() 21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Render target 21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) 21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // set limits 21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_numLayers = 8; 21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering to 2d texture array, numLayers = " << m_numLayers << tcu::TestLog::EndMessage; 21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genTextures(1, &m_texture); 21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture); 21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, RENDER_SIZE, RENDER_SIZE, m_numLayers); 21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen texture"); 21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Gen program 21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ProgramSources sources; 21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int tessGenLevel = -1; 21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::VertexSource(getVertexSource()) 21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()); 21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Tessellation limits 21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_TESSELLATION_MAX_IMPLEMENTATION) 21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_TESS_GEN_LEVEL, &tessGenLevel); 21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query tessellation limits"); 21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_TESSELLATION_MAX_SPEC) 22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessGenLevel = 64; 22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tessGenLevel = 5; 22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Tessellation level: " << tessGenLevel << ", mode = quad.\n" 22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tEach input patch produces " << (tessGenLevel*tessGenLevel) << " (" << (tessGenLevel*tessGenLevel*2) << " triangles)\n" 22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::TessellationControlSource(getTessellationControlSource(tessGenLevel)) 22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource(tessGenLevel)); 22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Geometry limits 22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryOutputComponents = -1; 22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryOutputVertices = -1; 22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryTotalOutputComponents = -1; 22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryShaderInvocations = -1; 22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool logGeometryLimits = false; 22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool logInvocationLimits = false; 22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_MAX_IMPLEMENTATION) 22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Using implementation maximum geometry shader output limits." << tcu::TestLog::EndMessage; 22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &geometryOutputComponents); 22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &geometryOutputVertices); 22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &geometryTotalOutputComponents); 22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry limits"); 22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logGeometryLimits = true; 22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_MAX_SPEC) 22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Using geometry shader extension minimum maximum output limits." << tcu::TestLog::EndMessage; 22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputComponents = 128; 22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputVertices = 256; 22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryTotalOutputComponents = 1024; 22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logGeometryLimits = true; 22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputComponents = 128; 22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryOutputVertices = 16; 22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryTotalOutputComponents = 1024; 22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION) 22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.getIntegerv(GL_MAX_GEOMETRY_SHADER_INVOCATIONS, &geometryShaderInvocations); 22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "query geometry invocation limits"); 22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logInvocationLimits = true; 22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC) 22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryShaderInvocations = 32; 22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry logInvocationLimits = true; 22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryShaderInvocations = 4; 22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logGeometryLimits || logInvocationLimits) 22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::MessageBuilder msg(&m_testCtx.getLog()); 22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "Geometry shader, targeting following limits:\n"; 22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logGeometryLimits) 22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "\tGL_MAX_GEOMETRY_OUTPUT_COMPONENTS = " << geometryOutputComponents << "\n" 22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tGL_MAX_GEOMETRY_OUTPUT_VERTICES = " << geometryOutputVertices << "\n" 22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = " << geometryTotalOutputComponents << "\n"; 22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (logInvocationLimits) 22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << "\tGL_MAX_GEOMETRY_SHADER_INVOCATIONS = " << geometryShaderInvocations; 22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry msg << tcu::TestLog::EndMessage; 22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool separatePrimitives = (m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) != 0; 22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numComponentsPerVertex = 8; // vec4 pos, vec4 color 22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numVerticesPerInvocation; 22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numPrimitivesPerInvocation; 22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryVerticesPerPrimitive; 22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int geometryPrimitivesOutPerPrimitive; 22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (separatePrimitives) 22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numComponentLimit = geometryTotalOutputComponents / (4 * numComponentsPerVertex); 23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numOutputLimit = geometryOutputVertices / 4; 23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numPrimitivesPerInvocation = de::min(numComponentLimit, numOutputLimit); 23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVerticesPerInvocation = numPrimitivesPerInvocation * 4; 23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If FLAG_GEOMETRY_SEPARATE_PRIMITIVES is not set, geometry shader fills a rectangle area in slices. 23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Each slice is a triangle strip and is generated by a single shader invocation. 23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // One slice with 4 segment ends (nodes) and 3 segments: 23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .__.__.__. 23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // |\ |\ |\ | 23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // |_\|_\|_\| 23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodesComponentLimit = geometryTotalOutputComponents / (2 * numComponentsPerVertex); // each node 2 vertices 23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodesOutputLimit = geometryOutputVertices / 2; // each node 2 vertices 23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numSliceNodes = de::min(numSliceNodesComponentLimit, numSliceNodesOutputLimit); 23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numVerticesPerInvocation = numSliceNodes * 2; 23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry numPrimitivesPerInvocation = (numSliceNodes - 1) * 2; 23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryVerticesPerPrimitive = numVerticesPerInvocation * geometryShaderInvocations; 23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry geometryPrimitivesOutPerPrimitive = numPrimitivesPerInvocation * geometryShaderInvocations; 23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Geometry shader:\n" 23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output vertex count per invocation: " << (numVerticesPerInvocation) << "\n" 23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output primitive count per invocation: " << (numPrimitivesPerInvocation) << "\n" 23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tNumber of invocations per primitive: " << geometryShaderInvocations << "\n" 23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output vertex count per input primitive: " << (geometryVerticesPerPrimitive) << "\n" 23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal output primitive count per input primitive: " << (geometryPrimitivesOutPerPrimitive) << "\n" 23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry sources << glu::GeometrySource(getGeometryShaderSource(numPrimitivesPerInvocation, geometryShaderInvocations, tessGenLevel)); 23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Program:\n" 23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal program output vertices count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryVerticesPerPrimitive) << "\n" 23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\tTotal program output primitive count per input patch: " << (tessGenLevel*tessGenLevel*2 * geometryPrimitivesOutPerPrimitive) << "\n" 23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), sources); 23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("failed to build program"); 23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::deinit (void) 23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_texture) 23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture); 23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_texture = 0; 23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGridRenderCase::IterateResult GridRenderCase::iterate (void) 23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<tcu::Surface> renderedLayers (m_numLayers); 23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allLayersOk = true; 23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numLayers; ++ndx) 23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderedLayers[ndx].setSize(RENDER_SIZE, RENDER_SIZE); 23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23733c827367444ee418f129b2c238299f49d3264554Jarkko 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; 23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry try 23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderTo(renderedLayers); 23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry catch (const AllowedRenderFailureException& ex) 23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Got accepted failure 23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message 23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Could not render, reason: " << ex.what() << "\n" 23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "Failure is allowed." 23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndMessage; 23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_numLayers; ++ndx) 23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allLayersOk &= verifyResultLayer(ndx, renderedLayers[ndx]); 23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (allLayersOk) 23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed"); 23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GridRenderCase::renderTo (std::vector<tcu::Surface>& dst) 24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int positionLocation = gl.getAttribLocation(m_program->getProgram(), "a_position"); 24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::MovePtr<glu::Framebuffer> fbo; 24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (positionLocation == -1) 24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("Attribute a_position location was -1"); 24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, dst.front().getWidth(), dst.front().getHeight()); 24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "viewport"); 24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind vao"); 24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttrib4f(positionLocation, 0.0f, 0.0f, 0.0f, 1.0f); 24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) 24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clear texture contents 24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Framebuffer clearFbo(m_context.getRenderContext()); 24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, *clearFbo); 24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx) 24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, layerNdx); 24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear tex contents"); 24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // create and bind layered fbo 24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry fbo = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext())); 24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, **fbo); 24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0); 24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen fbo"); 24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // clear viewport 24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // draw 24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glw::GLenum glerror; 24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 1); 24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glerror = gl.getError(); 24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (glerror == GL_OUT_OF_MEMORY && (m_flags & FLAG_ALLOW_OUT_OF_MEMORY)) 24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw AllowedRenderFailureException("got GL_OUT_OF_MEMORY while drawing"); 24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(glerror, "draw patches"); 24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read layers 24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) 24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Framebuffer readFbo(m_context.getRenderContext()); 24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, *readFbo); 24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int layerNdx = 0; layerNdx < m_numLayers; ++layerNdx) 24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texture, 0, layerNdx); 24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst[layerNdx].getAccess()); 24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels"); 24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::readPixels(m_context.getRenderContext(), 0, 0, dst.front().getAccess()); 24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "read pixels"); 24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool GridRenderCase::verifyResultLayer (int layerNdx, const tcu::Surface& image) 24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Surface errorMask (image.getWidth(), image.getHeight()); 24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool foundError = false; 24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::clear(errorMask.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output layer " << layerNdx << tcu::TestLog::EndMessage; 24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < image.getHeight(); ++y) 25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < image.getWidth(); ++x) 25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int threshold = 8; 25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const tcu::RGBA color = image.getPixel(x, y); 25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Color must be a linear combination of green and yellow 25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (color.getGreen() < 255 - threshold || color.getBlue() > threshold) 25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry errorMask.setPixel(x, y, tcu::RGBA::red); 25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry foundError = true; 25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!foundError) 25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message << "Image valid." << tcu::TestLog::EndMessage 25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::ImageSet("ImageVerification", "Image verification") 25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("Result", "Rendered result", image.getAccess()) 25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndImageSet; 25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() 25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Message << "Image verification failed, found invalid pixels." << tcu::TestLog::EndMessage 25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::ImageSet("ImageVerification", "Image verification") 25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("Result", "Rendered result", image.getAccess()) 25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask.getAccess()) 25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << tcu::TestLog::EndImageSet; 25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getVertexSource (void) 25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_positionVertexShader; 25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* GridRenderCase::getFragmentSource (void) 25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "flat in mediump vec4 v_color;\n" 25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(location = 0) out mediump vec4 fragColor;\n" 25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " fragColor = v_color;\n" 25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationControlSource (int tessLevel) 25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices=1) out;\n" 25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = " << tessLevel << ".0;\n" 25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = " << tessLevel << ".0;\n" 25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = " << tessLevel << ".0;\n" 25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[3] = " << tessLevel << ".0;\n" 25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = " << tessLevel << ".0;\n" 25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[1] = " << tessLevel << ".0;\n" 25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getTessellationEvaluationSource (int tessLevel) 25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(quads) in;\n" 25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out mediump ivec2 v_tessellationGridPosition;\n" 25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main (void)\n" 25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n"; 25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & (FLAG_GEOMETRY_SCATTER_INSTANCES | FLAG_GEOMETRY_SCATTER_PRIMITIVES | FLAG_GEOMETRY_SCATTER_LAYERS)) 25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Cover only a small area in a corner. The area will be expanded in geometry shader to cover whole viewport\n" 25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.x * 0.3 - 1.0, gl_TessCoord.y * 0.3 - 1.0, 0.0, 1.0);\n"; 25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Fill the whole viewport\n" 25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(gl_TessCoord.x * 2.0 - 1.0, gl_TessCoord.y * 2.0 - 1.0, 0.0, 1.0);\n"; 25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Calculate position in tessellation grid\n" 25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_tessellationGridPosition = ivec2(round(gl_TessCoord.xy * float(" << tessLevel << ")));\n" 25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystd::string GridRenderCase::getGeometryShaderSource (int numPrimitives, int numInstances, int tessLevel) 26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::ostringstream buf; 26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "#version 310 es\n" 26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(triangles, invocations=" << numInstances << ") in;\n" 26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(triangle_strip, max_vertices=" << ((m_flags & FLAG_GEOMETRY_SEPARATE_PRIMITIVES) ? (4 * numPrimitives) : (numPrimitives + 2)) << ") out;\n" 26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in mediump ivec2 v_tessellationGridPosition[];\n" 26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "flat out highp vec4 v_color;\n" 26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main ()\n" 26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " const float equalThreshold = 0.001;\n" 26153c827367444ee418f129b2c238299f49d3264554Jarkko 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" 26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Input triangle is generated from an axis-aligned rectangle by splitting it in half\n" 26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Original rectangle can be found by finding the bounding AABB of the triangle\n" 26193c827367444ee418f129b2c238299f49d3264554Jarkko 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" 26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " min(gl_in[0].gl_Position.y, min(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)),\n" 26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " max(gl_in[0].gl_Position.x, max(gl_in[1].gl_Position.x, gl_in[2].gl_Position.x)),\n" 26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " max(gl_in[0].gl_Position.y, max(gl_in[1].gl_Position.y, gl_in[2].gl_Position.y)));\n" 26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Location in tessellation grid\n" 26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 gridPosition = ivec2(min(v_tessellationGridPosition[0], min(v_tessellationGridPosition[1], v_tessellationGridPosition[2])));\n" 26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Which triangle of the two that split the grid cell\n" 26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " int numVerticesOnBottomEdge = 0;\n" 26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < 3; ++ndx)\n" 26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " if (abs(gl_in[ndx].gl_Position.y - aabb.w) < equalThreshold)\n" 26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ++numVerticesOnBottomEdge;\n" 26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " bool isBottomTriangle = numVerticesOnBottomEdge == 2;\n" 26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n"; 26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SCATTER_PRIMITIVES) 26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // scatter primitives 26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Draw grid cells\n" 26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " int inputTriangleNdx = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n" 26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < " << numPrimitives << "; ++ndx)\n" 26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 dstGridSize = ivec2(" << tessLevel << " * " << numPrimitives << ", 2 * " << tessLevel << " * " << numInstances << ");\n" 26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 dstGridNdx = ivec2(" << tessLevel << " * ndx + gridPosition.x, " << tessLevel << " * inputTriangleNdx + 2 * gridPosition.y + ndx * 127) % dstGridSize;\n" 26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 dstArea;\n" 26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.x = float(dstGridNdx.x) / float(dstGridSize.x) * 2.0 - 1.0 - gapOffset;\n" 26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.y = float(dstGridNdx.y) / float(dstGridSize.y) * 2.0 - 1.0 - gapOffset;\n" 26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.z = float(dstGridNdx.x+1) / float(dstGridSize.x) * 2.0 - 1.0 + gapOffset;\n" 26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.w = float(dstGridNdx.y+1) / float(dstGridSize.y) * 2.0 - 1.0 + gapOffset;\n" 26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n" 26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputColor = (((dstGridNdx.y + dstGridNdx.x) % 2) == 0) ? (green) : (yellow);\n" 26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.x, dstArea.y, 0.0, 1.0);\n" 26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.x, dstArea.w, 0.0, 1.0);\n" 26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.z, dstArea.y, 0.0, 1.0);\n" 26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.z, dstArea.w, 0.0, 1.0);\n" 26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n" 26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else if (m_flags & FLAG_GEOMETRY_SCATTER_LAYERS) 26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Number of subrectangle instances = num layers 26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(m_numLayers == numInstances * 2); 26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Draw grid cells, send each primitive to a separate layer\n" 26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " int baseLayer = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n" 26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < " << numPrimitives << "; ++ndx)\n" 26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 dstGridSize = ivec2(" << tessLevel << " * " << numPrimitives << ", " << tessLevel << ");\n" 26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 dstGridNdx = ivec2((gridPosition.x * " << numPrimitives << " * 7 + ndx)*13, (gridPosition.y * 127 + ndx) * 19) % dstGridSize;\n" 26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 dstArea;\n" 26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.x = float(dstGridNdx.x) / float(dstGridSize.x) * 2.0 - 1.0 - gapOffset;\n" 26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.y = float(dstGridNdx.y) / float(dstGridSize.y) * 2.0 - 1.0 - gapOffset;\n" 26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.z = float(dstGridNdx.x+1) / float(dstGridSize.x) * 2.0 - 1.0 + gapOffset;\n" 26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " dstArea.w = float(dstGridNdx.y+1) / float(dstGridSize.y) * 2.0 - 1.0 + gapOffset;\n" 26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n" 26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputColor = (((dstGridNdx.y + dstGridNdx.x) % 2) == 0) ? (green) : (yellow);\n" 26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.x, dstArea.y, 0.0, 1.0);\n" 26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Layer = ((baseLayer + ndx) * 11) % " << m_numLayers << ";\n" 26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.x, dstArea.w, 0.0, 1.0);\n" 26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Layer = ((baseLayer + ndx) * 11) % " << m_numLayers << ";\n" 27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.z, dstArea.y, 0.0, 1.0);\n" 27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Layer = ((baseLayer + ndx) * 11) % " << m_numLayers << ";\n" 27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(dstArea.z, dstArea.w, 0.0, 1.0);\n" 27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Layer = ((baseLayer + ndx) * 11) % " << m_numLayers << ";\n" 27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n" 27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_flags & FLAG_GEOMETRY_SCATTER_INSTANCES) 27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Scatter slices\n" 27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " int inputTriangleNdx = gl_InvocationID * 2 + ((isBottomTriangle) ? (1) : (0));\n" 27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 srcSliceNdx = ivec2(gridPosition.x, gridPosition.y * " << (numInstances*2) << " + inputTriangleNdx);\n" 27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " ivec2 dstSliceNdx = ivec2(7 * srcSliceNdx.x, 127 * srcSliceNdx.y) % ivec2(" << tessLevel << ", " << tessLevel << " * " << (numInstances*2) << ");\n" 27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Draw slice to the dstSlice slot\n" 27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputSliceArea;\n" 27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.x = float(dstSliceNdx.x) / float(" << tessLevel << ") * 2.0 - 1.0 - gapOffset;\n" 27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.y = float(dstSliceNdx.y) / float(" << (tessLevel * numInstances * 2) << ") * 2.0 - 1.0 - gapOffset;\n" 27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.z = float(dstSliceNdx.x+1) / float(" << tessLevel << ") * 2.0 - 1.0 + gapOffset;\n" 27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.w = float(dstSliceNdx.y+1) / float(" << (tessLevel * numInstances * 2) << ") * 2.0 - 1.0 + gapOffset;\n"; 27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << " // Fill the input area with slices\n" 27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Upper triangle produces slices only to the upper half of the quad and vice-versa\n" 27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float triangleOffset = (isBottomTriangle) ? ((aabb.w + aabb.y) / 2.0) : (aabb.y);\n" 27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Each slice is a invocation\n" 27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float sliceHeight = (aabb.w - aabb.y) / float(2 * " << numInstances << ");\n" 27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float invocationOffset = float(gl_InvocationID) * sliceHeight;\n" 27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputSliceArea;\n" 27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.x = aabb.x - gapOffset;\n" 27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.y = triangleOffset + invocationOffset - gapOffset;\n" 27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.z = aabb.z + gapOffset;\n" 27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " outputSliceArea.w = triangleOffset + invocationOffset + sliceHeight + gapOffset;\n"; 27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "\n" 27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " // Draw slice\n" 27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < " << ((numPrimitives+2)/2) << "; ++ndx)\n" 27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" 27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 yellow = vec4(1.0, 1.0, 0.0, 1.0);\n" 27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " vec4 outputColor = (((gl_InvocationID + ndx) % 2) == 0) ? (green) : (yellow);\n" 27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " float xpos = mix(outputSliceArea.x, outputSliceArea.z, float(ndx) / float(" << (numPrimitives/2) << "));\n" 27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(xpos, outputSliceArea.y, 0.0, 1.0);\n" 27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "\n" 27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = vec4(xpos, outputSliceArea.w, 0.0, 1.0);\n" 27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " v_color = outputColor;\n" 27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n"; 27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buf << "}\n"; 27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return buf.str(); 27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FeedbackRecordVariableSelectionCase : public TestCase 27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackRecordVariableSelectionCase (Context& context, const char* name, const char* description); 27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~FeedbackRecordVariableSelectionCase (void); 27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getVertexSource (void); 27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getFragmentSource (void); 27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getTessellationControlSource (void); 27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getTessellationEvaluationSource (void); 27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* getGeometrySource (void); 27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_xfbBuf; 27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackRecordVariableSelectionCase::FeedbackRecordVariableSelectionCase (Context& context, const char* name, const char* description) 27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, description) 27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_xfbBuf (0) 27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 27993c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackRecordVariableSelectionCase::~FeedbackRecordVariableSelectionCase (void) 28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deinit(); 28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackRecordVariableSelectionCase::init (void) 28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") || 28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader")) 28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader and GL_EXT_geometry_shader extensions"); 28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Declaring multiple output variables with the same name in multiple shader stages. Capturing the value of the varying using transform feedback." << tcu::TestLog::EndMessage; 28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen feedback buffer fit for 1 triangle (4 components) 28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const tcu::Vec4 initialData[3] = 28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f), 28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f), 28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4(-1.0f, -1.0f, -1.0f, -1.0f), 28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Creating buffer for transform feedback. Allocating storage for one triangle. Filling with -1.0" << tcu::TestLog::EndMessage; 28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genBuffers(1, &m_xfbBuf); 28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_xfbBuf); 28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (int)(sizeof(tcu::Vec4[3])), initialData, GL_DYNAMIC_READ); 28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "gen xfb buf"); 28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // gen shader 28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::VertexSource(getVertexSource()) 28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::FragmentSource(getFragmentSource()) 28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationControlSource(getTessellationControlSource()) 28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TessellationEvaluationSource(getTessellationEvaluationSource()) 28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::GeometrySource(getGeometrySource()) 28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackMode(GL_INTERLEAVED_ATTRIBS) 28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << glu::TransformFeedbackVarying("tf_feedback")); 28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << *m_program; 28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!m_program->isOk()) 28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("could not build program"); 28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FeedbackRecordVariableSelectionCase::deinit (void) 28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_xfbBuf) 28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_xfbBuf); 28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_xfbBuf = 0; 28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFeedbackRecordVariableSelectionCase::IterateResult FeedbackRecordVariableSelectionCase::iterate (void) 28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int posLoc = gl.getAttribLocation(m_program->getProgram(), "a_position"); 28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glu::VertexArray vao (m_context.getRenderContext()); 28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (posLoc == -1) 28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("a_position attribute location was -1"); 28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Rendering a patch of size 1." << tcu::TestLog::EndMessage; 28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Render and feed back 28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.viewport(0, 0, 1, 1); 28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.clear(GL_COLOR_BUFFER_BIT); 28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "clear"); 28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindVertexArray(*vao); 28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray"); 28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.vertexAttrib4f(posLoc, 0.0f, 0.0f, 0.0f, 1.0f); 28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "vertexAttrib4f"); 28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(m_program->getProgram()); 28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "use program"); 28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.patchParameteri(GL_PATCH_VERTICES, 1); 28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "set patch param"); 28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbBuf); 28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "bind xfb buf"); 28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.beginTransformFeedback(GL_TRIANGLES); 28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "beginTransformFeedback"); 28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.drawArrays(GL_PATCHES, 0, 1); 28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays"); 28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.endTransformFeedback(); 29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "beginTransformFeedback"); 29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Verifying the value of tf_feedback using transform feedback, expecting (3.0, 3.0, 3.0, 3.0)." << tcu::TestLog::EndMessage; 29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Read back result (one triangle) 29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec4 feedbackValues[3]; 29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const void* mapPtr = gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, (int)sizeof(feedbackValues), GL_MAP_READ_BIT); 29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "mapBufferRange"); 29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (mapPtr == DE_NULL) 29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("mapBufferRange returned null"); 29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deMemcpy(feedbackValues, mapPtr, sizeof(feedbackValues)); 29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER) != GL_TRUE) 29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry throw tcu::TestError("unmapBuffer did not return TRUE"); 29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < 3; ++ndx) 29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!tcu::boolAll(tcu::lessThan(tcu::abs(feedbackValues[ndx] - tcu::Vec4(3.0f)), tcu::Vec4(0.001f)))) 29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << tcu::TestLog::Message << "Feedback vertex " << ndx << ": expected (3.0, 3.0, 3.0, 3.0), got " << feedbackValues[ndx] << tcu::TestLog::EndMessage; 29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got unexpected feedback results"); 29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackRecordVariableSelectionCase::getVertexSource (void) 29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "in highp vec4 a_position;\n" 29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 tf_feedback;\n" 29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = a_position;\n" 29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_feedback = vec4(1.0, 1.0, 1.0, 1.0);\n" 29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackRecordVariableSelectionCase::getFragmentSource (void) 29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return s_whiteOutputFragmentShader; 29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackRecordVariableSelectionCase::getTessellationControlSource (void) 29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(vertices=3) out;\n" 29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n" 29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[0] = 1.0;\n" 29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[1] = 1.0;\n" 29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelOuter[2] = 1.0;\n" 29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_TessLevelInner[0] = 1.0;\n" 29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackRecordVariableSelectionCase::getTessellationEvaluationSource (void) 29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_tessellation_shader : require\n" 29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout(triangles) in;\n" 29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 tf_feedback;\n" 29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[0].gl_Position * gl_TessCoord.x + gl_in[1].gl_Position * gl_TessCoord.y + gl_in[2].gl_Position * gl_TessCoord.z;\n" 29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_feedback = vec4(2.0, 2.0, 2.0, 2.0);\n" 29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* FeedbackRecordVariableSelectionCase::getGeometrySource (void) 29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return "#version 310 es\n" 29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "#extension GL_EXT_geometry_shader : require\n" 29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (triangles) in;\n" 29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "layout (triangle_strip, max_vertices=3) out;\n" 29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "out highp vec4 tf_feedback;\n" 29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "void main()\n" 29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "{\n" 29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " for (int ndx = 0; ndx < 3; ++ndx)\n" 29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " {\n" 29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " gl_Position = gl_in[ndx].gl_Position + vec4(float(ndx), float(ndx)*float(ndx), 0.0, 0.0);\n" 29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " tf_feedback = vec4(3.0, 3.0, 3.0, 3.0);\n" 29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EmitVertex();\n" 29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " }\n" 29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry " EndPrimitive();\n" 29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "}\n"; 29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 29973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::TessellationGeometryInteractionTests (Context& context) 29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "tessellation_geometry_interaction", "Tessellation and geometry shader interaction tests") 29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30023c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTessellationGeometryInteractionTests::~TessellationGeometryInteractionTests (void) 30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TessellationGeometryInteractionTests::init (void) 30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const renderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Various render tests"); 30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const feedbackGroup = new tcu::TestCaseGroup(m_testCtx, "feedback", "Test transform feedback"); 30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const pointSizeGroup = new tcu::TestCaseGroup(m_testCtx, "point_size", "Test point size"); 30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(renderGroup); 30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(feedbackGroup); 30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(pointSizeGroup); 30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .render 30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const passthroughGroup = new tcu::TestCaseGroup(m_testCtx, "passthrough", "Render various types with either passthrough geometry or tessellation shader"); 30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const limitGroup = new tcu::TestCaseGroup(m_testCtx, "limits", "Render with properties near their limits"); 30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* const scatterGroup = new tcu::TestCaseGroup(m_testCtx, "scatter", "Scatter output primitives"); 30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderGroup->addChild(passthroughGroup); 30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderGroup->addChild(limitGroup); 30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry renderGroup->addChild(scatterGroup); 30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .passthrough 30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tessellate_tris_passthrough_geometry_no_change 30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tessellate_quads_passthrough_geometry_no_change 30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tessellate_isolines_passthrough_geometry_no_change 30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passthroughGroup->addChild(new IdentityGeometryShaderCase(m_context, "tessellate_tris_passthrough_geometry_no_change", "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_TRIANGLES)); 30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passthroughGroup->addChild(new IdentityGeometryShaderCase(m_context, "tessellate_quads_passthrough_geometry_no_change", "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_QUADS)); 30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passthroughGroup->addChild(new IdentityGeometryShaderCase(m_context, "tessellate_isolines_passthrough_geometry_no_change", "Passthrough geometry shader has no effect", IdentityGeometryShaderCase::CASE_ISOLINES)); 30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // passthrough_tessellation_geometry_shade_triangles_no_change 30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // passthrough_tessellation_geometry_shade_lines_no_change 30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passthroughGroup->addChild(new IdentityTessellationShaderCase(m_context, "passthrough_tessellation_geometry_shade_triangles_no_change", "Passthrough tessellation shader has no effect", IdentityTessellationShaderCase::CASE_TRIANGLES)); 30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry passthroughGroup->addChild(new IdentityTessellationShaderCase(m_context, "passthrough_tessellation_geometry_shade_lines_no_change", "Passthrough tessellation shader has no effect", IdentityTessellationShaderCase::CASE_ISOLINES)); 30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .limits 30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct LimitCaseDef 30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* desc; 30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int flags; 30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } cases[] = 30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Test single limit 30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_tessellation", 30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Minimum maximum tessellation level", 30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_SPEC 30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_tessellation", 30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Maximum tessellation level supported by the implementation", 30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_TESSELLATION_MAX_IMPLEMENTATION 30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_geometry", 30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Output minimum maximum number of vertices the geometry shader", 30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_MAX_SPEC 30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_geometry", 30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Output maximum number of vertices in the geometry shader supported by the implementation", 30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_MAX_IMPLEMENTATION 30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_required_max_invocations", 30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Minimum maximum number of geometry shader invocations", 30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_SPEC 30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "output_implementation_max_invocations", 30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Maximum number of geometry shader invocations supported by the implementation", 30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_INVOCATIONS_MAX_IMPLEMENTATION 30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ++ndx) 30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry limitGroup->addChild(new GridRenderCase(m_context, cases[ndx].name, cases[ndx].desc, cases[ndx].flags)); 30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .scatter 30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry scatterGroup->addChild(new GridRenderCase(m_context, 30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "geometry_scatter_instances", 30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Each geometry shader instance outputs its primitives far from other instances of the same execution", 30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_SCATTER_INSTANCES)); 30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry scatterGroup->addChild(new GridRenderCase(m_context, 30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "geometry_scatter_primitives", 30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Each geometry shader instance outputs its primitives far from other primitives of the same instance", 30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_SCATTER_PRIMITIVES | GridRenderCase::FLAG_GEOMETRY_SEPARATE_PRIMITIVES)); 30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry scatterGroup->addChild(new GridRenderCase(m_context, 30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "geometry_scatter_layers", 30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Each geometry shader instance outputs its primitives to multiple layers and far from other primitives of the same instance", 31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GridRenderCase::FLAG_GEOMETRY_SCATTER_LAYERS | GridRenderCase::FLAG_GEOMETRY_SEPARATE_PRIMITIVES)); 31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .feedback 31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct PrimitiveCaseConfig 31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* description; 31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TessellationOutputType tessellationOutput; 31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TessellationPointMode tessellationPointMode; 31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GeometryOutputType geometryOutputType; 31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } caseConfigs[] = 31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output triangles -> geo input triangles, output points 31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_triangles_geometry_output_points", 31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs triangles, geometry outputs points", 31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_TRIANGLES, 31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF, 31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS 31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output quads <-> geo input triangles, output points 31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_quads_geometry_output_points", 31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs quads, geometry outputs points", 31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_QUADS, 31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF, 31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS 31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output isolines <-> geo input lines, output points 31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_isolines_geometry_output_points", 31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs isolines, geometry outputs points", 31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_ISOLINES, 31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_OFF, 31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_POINTS 31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output triangles, point_mode <-> geo input points, output lines 31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_triangles_point_mode_geometry_output_lines", 31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs triangles in point mode, geometry outputs lines", 31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_TRIANGLES, 31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON, 31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_LINES 31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output quads, point_mode <-> geo input points, output lines 31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_quads_point_mode_geometry_output_lines", 31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs quads in point mode, geometry outputs lines", 31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_QUADS, 31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON, 31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_LINES 31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // tess output isolines, point_mode <-> geo input points, output triangles 31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "tessellation_output_isolines_point_mode_geometry_output_triangles", 31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry "Tessellation outputs isolines in point mode, geometry outputs triangles", 31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_OUT_ISOLINES, 31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::TESSELLATION_POINTMODE_ON, 31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FeedbackPrimitiveTypeCase::GEOMETRY_OUTPUT_TRIANGLES 31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }, 31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(caseConfigs); ++ndx) 31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry feedbackGroup->addChild(new FeedbackPrimitiveTypeCase(m_context, 31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseConfigs[ndx].name, 31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseConfigs[ndx].description, 31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseConfigs[ndx].tessellationOutput, 31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseConfigs[ndx].tessellationPointMode, 31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry caseConfigs[ndx].geometryOutputType)); 31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry feedbackGroup->addChild(new FeedbackRecordVariableSelectionCase(m_context, "record_variable_selection", "Record a variable that has been declared as an output variable in multiple shader stages")); 31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // .point_size 31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const int caseFlags[] = 31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET, 31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET, 31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_GEOMETRY_SET, 31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_CONTROL_SET, 31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET, 31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_DONT_SET, 31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_GEOMETRY_SET, 31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET | PointSizeCase::FLAG_GEOMETRY_SET, 31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_ADD | PointSizeCase::FLAG_GEOMETRY_ADD, 31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry PointSizeCase::FLAG_VERTEX_SET | PointSizeCase::FLAG_TESSELLATION_EVALUATION_SET | PointSizeCase::FLAG_GEOMETRY_DONT_SET, 31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(caseFlags); ++ndx) 32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string name = PointSizeCase::genTestCaseName(caseFlags[ndx]); 32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const std::string desc = PointSizeCase::genTestCaseDescription(caseFlags[ndx]); 32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry pointSizeGroup->addChild(new PointSizeCase(m_context, name.c_str(), desc.c_str(), caseFlags[ndx])); 32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles31 32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 3212