148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/*------------------------------------------------------------------------- 248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * OpenGL Conformance Test Suite 348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * ----------------------------- 448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Copyright (c) 2014-2016 The Khronos Group Inc. 648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License"); 848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * you may not use this file except in compliance with the License. 948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * You may obtain a copy of the License at 1048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * http://www.apache.org/licenses/LICENSE-2.0 1248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Unless required by applicable law or agreed to in writing, software 1448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS, 1548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * See the License for the specific language governing permissions and 1748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * limitations under the License. 1848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 1984322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*! 2048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \file 2148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * \brief 2284322c9402f810da3cd80b52e9f9ef72150a9004Alexander Galazin */ /*-------------------------------------------------------------------*/ 2348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 2448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "esextcGeometryShaderConstantVariables.hpp" 2548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluContextInfo.hpp" 2648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "gluDefs.hpp" 2748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwEnums.hpp" 2848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "glwFunctions.hpp" 2948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos#include "tcuTestLog.hpp" 3048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosnamespace glcts 3248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 3348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 3448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Fragment shader code */ 3548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GeometryShaderConstantVariables::m_fragment_shader_code = "${VERSION}\n" 3648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 3748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 3848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 3948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "out vec4 color;\n" 4048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 4148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 4248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 4348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " color = vec4(1, 1, 1, 1);\n" 4448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 4548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 4648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Geometry shader code */ 4748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GeometryShaderConstantVariables::m_geometry_shader_code = 4848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "${VERSION}\n" 4948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 5048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "${GEOMETRY_SHADER_REQUIRE}\n" 5148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 5248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 5348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 5448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points) in;\n" 5548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "layout(points, max_vertices=1) out;\n" 5648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 5748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryInputComponents;\n" 5848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryOutputComponents;\n" 5948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryTextureImageUnits;\n" 6048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryOutputVertices;\n" 6148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryTotalOutputComponents;\n" 6248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryUniformComponents;\n" 6348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryAtomicCounters;\n" 6448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryAtomicCounterBuffers;\n" 6548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "flat out int test_MaxGeometryImageUniforms;\n" 6648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 6748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 6848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 6948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryInputComponents = gl_MaxGeometryInputComponents;\n" 7048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryOutputComponents = gl_MaxGeometryOutputComponents;\n" 7148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryTextureImageUnits = gl_MaxGeometryTextureImageUnits;\n" 7248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryOutputVertices = gl_MaxGeometryOutputVertices;\n" 7348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryTotalOutputComponents = gl_MaxGeometryTotalOutputComponents;\n" 7448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryUniformComponents = gl_MaxGeometryUniformComponents;\n" 7548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryAtomicCounters = gl_MaxGeometryAtomicCounters;\n" 7648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryAtomicCounterBuffers = gl_MaxGeometryAtomicCounterBuffers;\n" 7748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " test_MaxGeometryImageUniforms = gl_MaxGeometryImageUniforms;\n" 7848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 7948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EmitVertex();\n" 8048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos " EndPrimitive();\n" 8148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 8248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 8348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Vertex shader code */ 8448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GeometryShaderConstantVariables::m_vertex_shader_code = "${VERSION}\n" 8548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 8648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "precision highp float;\n" 8748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "\n" 8848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "void main()\n" 8948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "{\n" 9048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "}\n"; 9148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/* Specify transform feedback varyings */ 9348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosconst char* GeometryShaderConstantVariables::m_feedbackVaryings[] = { 9448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "test_MaxGeometryInputComponents", "test_MaxGeometryOutputComponents", "test_MaxGeometryTextureImageUnits", 9548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "test_MaxGeometryOutputVertices", "test_MaxGeometryTotalOutputComponents", "test_MaxGeometryUniformComponents", 9648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos "test_MaxGeometryAtomicCounters", "test_MaxGeometryAtomicCounterBuffers", "test_MaxGeometryImageUniforms" 9748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos}; 9848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 9948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Constructor 10048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 10148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param context Test context 10248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param name Test case's name 10348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @param description Test case's desricption 10448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 10548087f5f0eb08759ee763f98daf3b34becb74559Pyry HaulosGeometryShaderConstantVariables::GeometryShaderConstantVariables(Context& context, const ExtParameters& extParams, 10648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const char* name, const char* description) 10748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos : TestCaseBase(context, extParams, name, description) 10848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_fragment_shader_id(0) 10948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_geometry_shader_id(0) 11048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vertex_shader_id(0) 11148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_program_id(0) 11248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_bo_id(0) 11348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_vao_id(0) 11448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryImagesUniforms(0) 11548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryTextureImagesUnits(16) 11648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryShaderStorageBlocks(0) 11748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryAtomicCounterBuffers(0) 11848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryAtomicCounters(0) 11948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxFramebufferLayers(256) 12048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryInputComponents(64) 12148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryOutputComponents(64) 12248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryOutputVertices(256) 12348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryShaderInvocations(32) 12448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryTotalOutputComponents(1024) 12548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryUniformBlocks(12) 12648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos , m_min_MaxGeometryUniformComponents(1024) 12748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 12848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Left blank intentionally */ 12948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 13048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 13148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Initializes GLES objects used during the test. 13248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 13348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 13448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderConstantVariables::initTest(void) 13548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 13648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* This test should only run if EXT_geometry_shader is supported */ 13748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!m_is_geometry_shader_extension_supported) 13848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 13948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 14048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 14148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 14348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create VAO */ 14548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genVertexArrays(1, &m_vao_id); 14648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create VAO!"); 14848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 14948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create a program object and set it up for TF */ 15048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_varyings = sizeof(m_feedbackVaryings) / sizeof(m_feedbackVaryings[0]); 15148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_id = gl.createProgram(); 15348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.transformFeedbackVaryings(m_program_id, n_varyings, m_feedbackVaryings, GL_INTERLEAVED_ATTRIBS); 15548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set program object for transform feedback"); 15748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 15848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create shaders */ 15948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER); 16048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 16148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER); 16248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 16348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Build the test program */ 16448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (!buildProgram(m_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code, m_geometry_shader_id, 1, 16548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos &m_geometry_shader_code, m_vertex_shader_id, 1, &m_vertex_shader_code)) 16648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 16748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TCU_FAIL("Program could not have been created from a valid vertex/geometry/fragment shader!"); 16848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 16948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Create and set up a buffer object we will use for the test */ 17148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.genBuffers(1, &m_bo_id); 17248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); 17348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint) * n_varyings, DE_NULL, GL_STATIC_COPY); 17448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ARRAY_BUFFER, 0); 17548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set a buffer object up"); 17748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 17848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 17948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Executes the test. 18048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 18148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 18248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * Note the function throws exception should an error occur! 18348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos **/ 18448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulostcu::TestNode::IterateResult GeometryShaderConstantVariables::iterate(void) 18548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 18648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos initTest(); 18748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 18848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 18948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Set up relevant bindings */ 19148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(m_vao_id); 19248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind a vertex array object"); 19348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id); 19548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind a buffer object!"); 19648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 19748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id); 19848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object to transform feedback binding point."); 19948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Prepare for rendering. */ 20148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(m_program_id); 20248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program"); 20348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.enable(GL_RASTERIZER_DISCARD); 20548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 20648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.beginTransformFeedback(GL_POINTS); 20748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 20848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Render */ 20948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 21048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 21148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.endTransformFeedback(); 21248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed."); 21348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.disable(GL_RASTERIZER_DISCARD); 21548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 21648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* First, retrieve the ES constant values using the API. */ 21748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const unsigned int n_varyings = sizeof(m_feedbackVaryings) / sizeof(m_feedbackVaryings[0]); 21848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint constant_values[n_varyings] = { 0 }; 21948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos unsigned int index = 0; 22048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_INPUT_COMPONENTS, &constant_values[index]); 22248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 22348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT failed."); 22448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &constant_values[index]); 22648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 22748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT failed."); 22848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 22948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &constant_values[index]); 23048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 23148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT failed."); 23248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 23348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &constant_values[index]); 23448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 23548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT failed."); 23648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 23748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &constant_values[index]); 23848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 23948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT failed."); 24048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &constant_values[index]); 24248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 24348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT failed."); 24448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &constant_values[index]); 24648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 24748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT failed."); 24848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 24948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &constant_values[index]); 25048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 25148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT failed."); 25248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 25348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &constant_values[index]); 25448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos index++; 25548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT failed."); 25648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 25748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::GLint* stored_data_ptr = (const glw::GLint*)gl.mapBufferRange( 25848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(glw::GLint) * n_varyings, GL_MAP_READ_BIT); 25948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map buffer object storage"); 26148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 26248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compare the values that were stored by the draw call with values 26348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * returned by the getter call. 26448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 26548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos bool has_failed = false; 26648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos for (unsigned int id = 0; id < n_varyings; ++id) 26748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 26848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (constant_values[id] != stored_data_ptr[id]) 26948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 27048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for ES constant " << m_feedbackVaryings[id] 27148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " in a shader: " << stored_data_ptr[id] 27248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " and via a glGetIntegerv() call: " << constant_values[id] << " do not match." 27348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 27448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 27548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 27648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 27748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 27848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 27948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check whether the reported values are at least of the minimum value described in relevant 28148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * extension specifications */ 28248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint int_value = 0; 28448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check values of ES constants specific to shader atomic counters */ 28648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &int_value); 28748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 28848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT"); 28948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryAtomicCounterBuffers) 29148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 29248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 29348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Reported GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT constant value " << int_value 29448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is smaller than required minimum value of " << m_min_MaxGeometryAtomicCounterBuffers 29548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 29648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 29748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 29848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 29948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &int_value); 30148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT"); 30348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 30448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryAtomicCounters) 30548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 30648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT constant value " 30748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 30848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryAtomicCounters << tcu::TestLog::EndMessage; 30948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 31148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 31248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check values of ES constants specific to image load store */ 31448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &int_value); 31548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT"); 31748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 31848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryImagesUniforms) 31948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 32048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT constant value " 32148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 32248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryImagesUniforms << tcu::TestLog::EndMessage; 32348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 32548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 32648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &int_value); 32848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 32948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT"); 33048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 33148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryTextureImagesUnits) 33248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 33348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 33448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Reported GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT constant value " << int_value 33548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is smaller than required minimum value of " << m_min_MaxGeometryTextureImagesUnits 33648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 33748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 33848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 33948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 34048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check values of ES constants specific to shader storage buffer objects */ 34248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &int_value); 34348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT"); 34548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 34648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryShaderStorageBlocks) 34748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 34848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 34948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Reported GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT constant value " << int_value 35048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is smaller than required minimum value of " << m_min_MaxGeometryShaderStorageBlocks 35148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 35248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 35448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 35548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &int_value); 35748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 35848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT"); 35948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryUniformComponents) 36148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 36248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT constant value " 36348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 36448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryUniformComponents << tcu::TestLog::EndMessage; 36548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 36748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 36848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 36948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Check EXT_geometry_shader specific constant values */ 37048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_BLOCKS, &int_value); 37148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT"); 37348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 37448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryUniformBlocks) 37548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 37648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT constant value " 37748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 37848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryUniformBlocks << tcu::TestLog::EndMessage; 37948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 38148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 38248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_INPUT_COMPONENTS, &int_value); 38448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT"); 38648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 38748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryInputComponents) 38848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 38948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT constant value " 39048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 39148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryInputComponents << tcu::TestLog::EndMessage; 39248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 39348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 39448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 39548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 39648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &int_value); 39748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 39848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT"); 39948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 40048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryOutputComponents) 40148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 40248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT constant value " 40348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 40448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryOutputComponents << tcu::TestLog::EndMessage; 40548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 40648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 40748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 40848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 40948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &int_value); 41048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT"); 41248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryOutputVertices) 41448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 41548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT constant value " 41648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 41748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryOutputVertices << tcu::TestLog::EndMessage; 41848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 41948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 42048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 42148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &int_value); 42348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT"); 42548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 42648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryTotalOutputComponents) 42748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 42848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 42948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Reported GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT constant value " << int_value 43048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is smaller than required minimum value of " << m_min_MaxGeometryTotalOutputComponents 43148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 43248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 43448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 43548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_INVOCATIONS, &int_value); 43748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 43848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT"); 43948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 44048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxGeometryShaderInvocations) 44148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 44248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT constant value " 44348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " 44448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << m_min_MaxGeometryShaderInvocations << tcu::TestLog::EndMessage; 44548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 44648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 44748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 44848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 44948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_FRAMEBUFFER_LAYERS, &int_value); 45048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_FRAMEBUFFER_LAYERS_EXT"); 45248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < m_min_MaxFramebufferLayers) 45448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 45548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_FRAMEBUFFER_LAYERS_EXT constant value " 45648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is smaller than required minimum value of " << m_min_MaxFramebufferLayers 45748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << tcu::TestLog::EndMessage; 45848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 45948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 46048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 46148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compute minimum value that is acceptable for gl_MaxCombinedGeometryUniformComponents */ 46348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_max_geometry_uniform_blocks = 0; 46448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_max_geometry_uniform_block_size = 0; 46548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_max_geometry_uniform_components = 0; 46648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_BLOCKS, &n_max_geometry_uniform_blocks); 46848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 46948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT."); 47048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &n_max_geometry_uniform_block_size); 47248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_UNIFORM_BLOCK_SIZE."); 47448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &n_max_geometry_uniform_components); 47648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT."); 47848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 47948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos glw::GLint n_max_combined_geometry_uniform_components = 48048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos n_max_geometry_uniform_blocks * n_max_geometry_uniform_block_size / 4 + n_max_geometry_uniform_components; 48148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Compare against actual constant value */ 48348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, &int_value); 48448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT."); 48648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 48748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (int_value < n_max_combined_geometry_uniform_components) 48848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 48948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message 49048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << "Reported GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT constant value " << int_value 49148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << " is smaller than required minimum value of " 49248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << n_max_combined_geometry_uniform_components << tcu::TestLog::EndMessage; 49348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 49548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 49648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 49748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Make sure value reported for GL_LAYER_PROVOKING_VERTEX_EXT is valid */ 49848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.getIntegerv(m_glExtTokens.LAYER_PROVOKING_VERTEX, &int_value); 49948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_LAYER_PROVOKING_VERTEX_EXT."); 50148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 50248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if ( 50348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* This value is allowed in Desktop OpenGL, but not in the ES 3.1 extension. */ 50448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (!glu::isContextTypeES(m_context.getRenderContext().getType()) && 50548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (glw::GLenum)int_value != GL_PROVOKING_VERTEX) && 50648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (glw::GLenum)int_value != m_glExtTokens.FIRST_VERTEX_CONVENTION && 50748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (glw::GLenum)int_value != m_glExtTokens.LAST_VERTEX_CONVENTION && 50848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos (glw::GLenum)int_value != m_glExtTokens.UNDEFINED_VERTEX) 50948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 51048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_LAYER_PROVOKING_VERTEX_EXT constant value " 51148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos << int_value << " is not among permissible values" << tcu::TestLog::EndMessage; 51248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos has_failed = true; 51448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 51548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 51648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (has_failed) 51748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 51848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 51948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 52148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 52248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 52448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos return STOP; 52648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 52748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 52848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos/** Deinitializes GLES objects created during the test. 52948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos * 53048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos */ 53148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulosvoid GeometryShaderConstantVariables::deinit(void) 53248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos{ 53348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 53448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 53548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Reset OpenGL ES state */ 53648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.useProgram(0); 53748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindBuffer(GL_ARRAY_BUFFER, 0); 53848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.bindVertexArray(0); 53948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Delete program object and shaders */ 54148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_program_id != 0) 54248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 54348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteProgram(m_program_id); 54448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_program_id = 0; 54648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 54748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 54848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vertex_shader_id != 0) 54948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 55048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_vertex_shader_id); 55148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vertex_shader_id = 0; 55348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 55448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_geometry_shader_id != 0) 55648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 55748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_geometry_shader_id); 55848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 55948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_geometry_shader_id = 0; 56048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 56148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_fragment_shader_id != 0) 56348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 56448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteShader(m_fragment_shader_id); 56548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_fragment_shader_id = 0; 56748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 56848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 56948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_bo_id != 0) 57048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 57148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteBuffers(1, &m_bo_id); 57248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_bo_id = 0; 57448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 57548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 57648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos if (m_vao_id != 0) 57748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos { 57848087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos gl.deleteVertexArrays(1, &m_vao_id); 57948087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58048087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos m_vao_id = 0; 58148087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos } 58248087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58348087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos /* Release base class */ 58448087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos TestCaseBase::deinit(); 58548087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} 58648087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos 58748087f5f0eb08759ee763f98daf3b34becb74559Pyry Haulos} // namespace glcts 588