1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015-2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci */ /*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief 22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci#include "esextcGeometryShaderAPI.hpp" 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 26e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 27e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 28e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 29e5c31af7Sopenharmony_ci#include <cstring> 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cinamespace glcts 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_cistatic const char* minimal_fs_code = 35e5c31af7Sopenharmony_ci "${VERSION}\n" 36e5c31af7Sopenharmony_ci "\n" 37e5c31af7Sopenharmony_ci "precision highp float;\n" 38e5c31af7Sopenharmony_ci "\n" 39e5c31af7Sopenharmony_ci "out vec4 result;\n" 40e5c31af7Sopenharmony_ci "\n" 41e5c31af7Sopenharmony_ci "void main()\n" 42e5c31af7Sopenharmony_ci "{\n" 43e5c31af7Sopenharmony_ci " result = vec4(1.0);\n" 44e5c31af7Sopenharmony_ci "}\n"; 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cistatic const char* minimal_gs_code = 47e5c31af7Sopenharmony_ci "${VERSION}\n" 48e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 49e5c31af7Sopenharmony_ci "\n" 50e5c31af7Sopenharmony_ci "layout (points) in;\n" 51e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 52e5c31af7Sopenharmony_ci "\n" 53e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}" 54e5c31af7Sopenharmony_ci "${IN_DATA_DECL}" 55e5c31af7Sopenharmony_ci "void main()\n" 56e5c31af7Sopenharmony_ci "{\n" 57e5c31af7Sopenharmony_ci "${POSITION_WITH_IN_DATA}" 58e5c31af7Sopenharmony_ci " EmitVertex();\n" 59e5c31af7Sopenharmony_ci "}\n"; 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_cistatic const char* minimal_vs_code = 62e5c31af7Sopenharmony_ci "${VERSION}\n" 63e5c31af7Sopenharmony_ci "\n" 64e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}" 65e5c31af7Sopenharmony_ci "\n" 66e5c31af7Sopenharmony_ci "void main()\n" 67e5c31af7Sopenharmony_ci "{\n" 68e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 69e5c31af7Sopenharmony_ci "}\n"; 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci/* createShaderProgramv conformance test shaders */ 72e5c31af7Sopenharmony_ciconst char* GeometryShaderCreateShaderProgramvTest::fs_code = "${VERSION}\n" 73e5c31af7Sopenharmony_ci "\n" 74e5c31af7Sopenharmony_ci "precision highp float;\n" 75e5c31af7Sopenharmony_ci "\n" 76e5c31af7Sopenharmony_ci "out vec4 result;\n" 77e5c31af7Sopenharmony_ci "\n" 78e5c31af7Sopenharmony_ci "void main()\n" 79e5c31af7Sopenharmony_ci "{\n" 80e5c31af7Sopenharmony_ci " result = vec4(0.0, 1.0, 0.0, 0.0);\n" 81e5c31af7Sopenharmony_ci "}\n"; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ciconst char* GeometryShaderCreateShaderProgramvTest::gs_code = "${VERSION}\n" 84e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 85e5c31af7Sopenharmony_ci "\n" 86e5c31af7Sopenharmony_ci "layout (points) in;\n" 87e5c31af7Sopenharmony_ci "layout (triangle_strip, max_vertices = 4) out;\n" 88e5c31af7Sopenharmony_ci "\n" 89e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}" 90e5c31af7Sopenharmony_ci "\n" 91e5c31af7Sopenharmony_ci "void main()\n" 92e5c31af7Sopenharmony_ci "{\n" 93e5c31af7Sopenharmony_ci " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" 94e5c31af7Sopenharmony_ci " EmitVertex();\n" 95e5c31af7Sopenharmony_ci "\n" 96e5c31af7Sopenharmony_ci " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 97e5c31af7Sopenharmony_ci " EmitVertex();\n" 98e5c31af7Sopenharmony_ci "\n" 99e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n" 100e5c31af7Sopenharmony_ci " EmitVertex();\n" 101e5c31af7Sopenharmony_ci "\n" 102e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n" 103e5c31af7Sopenharmony_ci " EmitVertex();\n" 104e5c31af7Sopenharmony_ci " EndPrimitive();\n" 105e5c31af7Sopenharmony_ci "}\n"; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ciconst char* GeometryShaderCreateShaderProgramvTest::vs_code = "${VERSION}\n" 108e5c31af7Sopenharmony_ci "\n" 109e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}" 110e5c31af7Sopenharmony_ci "\n" 111e5c31af7Sopenharmony_ci "void main()\n" 112e5c31af7Sopenharmony_ci "{\n" 113e5c31af7Sopenharmony_ci " gl_Position = vec4(-10.0, -10.0, -10.0, 0.0);\n" 114e5c31af7Sopenharmony_ci "}\n"; 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ciconst unsigned int GeometryShaderCreateShaderProgramvTest::m_to_height = 4; 117e5c31af7Sopenharmony_ciconst unsigned int GeometryShaderCreateShaderProgramvTest::m_to_width = 4; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci/** Constructor 120e5c31af7Sopenharmony_ci * 121e5c31af7Sopenharmony_ci * @param context Test context 122e5c31af7Sopenharmony_ci * @param extParams Not used. 123e5c31af7Sopenharmony_ci * @param name Test case's name 124e5c31af7Sopenharmony_ci * @param description Test case's description 125e5c31af7Sopenharmony_ci **/ 126e5c31af7Sopenharmony_ciGeometryShaderCreateShaderProgramvTest::GeometryShaderCreateShaderProgramvTest(Context& context, 127e5c31af7Sopenharmony_ci const ExtParameters& extParams, 128e5c31af7Sopenharmony_ci const char* name, 129e5c31af7Sopenharmony_ci const char* description) 130e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 131e5c31af7Sopenharmony_ci , m_fbo_id(0) 132e5c31af7Sopenharmony_ci , m_fs_po_id(0) 133e5c31af7Sopenharmony_ci , m_gs_po_id(0) 134e5c31af7Sopenharmony_ci , m_pipeline_object_id(0) 135e5c31af7Sopenharmony_ci , m_to_id(0) 136e5c31af7Sopenharmony_ci , m_vao_id(0) 137e5c31af7Sopenharmony_ci , m_vs_po_id(0) 138e5c31af7Sopenharmony_ci{ 139e5c31af7Sopenharmony_ci} 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 142e5c31af7Sopenharmony_civoid GeometryShaderCreateShaderProgramvTest::deinit() 143e5c31af7Sopenharmony_ci{ 144e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci if (m_fbo_id != 0) 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_fbo_id); 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci m_fbo_id = 0; 151e5c31af7Sopenharmony_ci } 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci if (m_fs_po_id != 0) 154e5c31af7Sopenharmony_ci { 155e5c31af7Sopenharmony_ci gl.deleteProgram(m_fs_po_id); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci m_fs_po_id = 0; 158e5c31af7Sopenharmony_ci } 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci if (m_gs_po_id != 0) 161e5c31af7Sopenharmony_ci { 162e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 163e5c31af7Sopenharmony_ci 164e5c31af7Sopenharmony_ci m_gs_po_id = 0; 165e5c31af7Sopenharmony_ci } 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci if (m_pipeline_object_id != 0) 168e5c31af7Sopenharmony_ci { 169e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_pipeline_object_id); 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci m_pipeline_object_id = 0; 172e5c31af7Sopenharmony_ci } 173e5c31af7Sopenharmony_ci 174e5c31af7Sopenharmony_ci if (m_to_id != 0) 175e5c31af7Sopenharmony_ci { 176e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_to_id); 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci m_to_id = 0; 179e5c31af7Sopenharmony_ci } 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci if (m_vao_id != 0) 182e5c31af7Sopenharmony_ci { 183e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci m_vao_id = 0; 186e5c31af7Sopenharmony_ci } 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci if (m_vs_po_id != 0) 189e5c31af7Sopenharmony_ci { 190e5c31af7Sopenharmony_ci gl.deleteProgram(m_vs_po_id); 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci m_vs_po_id = 0; 193e5c31af7Sopenharmony_ci } 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci /* Release base class */ 196e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 197e5c31af7Sopenharmony_ci} 198e5c31af7Sopenharmony_ci 199e5c31af7Sopenharmony_ci/** Initializes a framebuffer object used by the conformance test. */ 200e5c31af7Sopenharmony_civoid GeometryShaderCreateShaderProgramvTest::initFBO() 201e5c31af7Sopenharmony_ci{ 202e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci /* Generate a FBO */ 205e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_fbo_id); 206e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_ci /* Generate a TO */ 209e5c31af7Sopenharmony_ci gl.genTextures(1, &m_to_id); 210e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci /* Set the TO up */ 213e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_to_id); 214e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */ 217e5c31af7Sopenharmony_ci GL_RGBA8, m_to_width, m_to_height); 218e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci /* Set up the FBO */ 221e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 222e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0); /* level */ 225e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci /* Set up the viewport */ 228e5c31af7Sopenharmony_ci gl.viewport(0, /* x */ 229e5c31af7Sopenharmony_ci 0, /* y */ 230e5c31af7Sopenharmony_ci m_to_width, m_to_height); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed."); 233e5c31af7Sopenharmony_ci} 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci/* Initializes a pipeline object used by the conformance test */ 236e5c31af7Sopenharmony_civoid GeometryShaderCreateShaderProgramvTest::initPipelineObject() 237e5c31af7Sopenharmony_ci{ 238e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ci DE_ASSERT(m_fs_po_id != 0 && m_gs_po_id != 0 && m_vs_po_id != 0); 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &m_pipeline_object_id); 243e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id); 246e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id); 247e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_VERTEX_SHADER_BIT, m_vs_po_id); 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed."); 250e5c31af7Sopenharmony_ci} 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci/** Executes the test. 253e5c31af7Sopenharmony_ci * 254e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 255e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 256e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 257e5c31af7Sopenharmony_ci **/ 258e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderCreateShaderProgramvTest::iterate() 259e5c31af7Sopenharmony_ci{ 260e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 261e5c31af7Sopenharmony_ci const unsigned int n_so_po_ids = 3; 262e5c31af7Sopenharmony_ci bool result = true; 263e5c31af7Sopenharmony_ci glw::GLuint so_po_ids[n_so_po_ids]; 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 266e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 267e5c31af7Sopenharmony_ci { 268e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 269e5c31af7Sopenharmony_ci } 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci /* Initialize off-screen rendering */ 272e5c31af7Sopenharmony_ci initFBO(); 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci /* Form shader sources */ 275e5c31af7Sopenharmony_ci std::string fs_specialized_code = specializeShader(1, 276e5c31af7Sopenharmony_ci /* parts */ &fs_code); 277e5c31af7Sopenharmony_ci const char* fs_specialized_code_raw = fs_specialized_code.c_str(); 278e5c31af7Sopenharmony_ci std::string gs_specialized_code = specializeShader(1, 279e5c31af7Sopenharmony_ci /* parts */ &gs_code); 280e5c31af7Sopenharmony_ci const char* gs_specialized_code_raw = gs_specialized_code.c_str(); 281e5c31af7Sopenharmony_ci std::string vs_specialized_code = specializeShader(1, 282e5c31af7Sopenharmony_ci /* parts */ &vs_code); 283e5c31af7Sopenharmony_ci const char* vs_specialized_code_raw = vs_specialized_code.c_str(); 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci /* Try to create an invalid geometry shader program first */ 286e5c31af7Sopenharmony_ci glw::GLint link_status = GL_TRUE; 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */ 289e5c31af7Sopenharmony_ci &gs_code); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci if (m_gs_po_id == 0) 294e5c31af7Sopenharmony_ci { 295e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "glCreateShaderProgramv() call returned 0." 296e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci result = false; 299e5c31af7Sopenharmony_ci goto end; 300e5c31af7Sopenharmony_ci } 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci gl.getProgramiv(m_gs_po_id, GL_LINK_STATUS, &link_status); 303e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci if (link_status != GL_FALSE) 306e5c31af7Sopenharmony_ci { 307e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "An invalid shader program was linked successfully." 308e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci result = false; 311e5c31af7Sopenharmony_ci goto end; 312e5c31af7Sopenharmony_ci } 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 315e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed."); 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci /* Create shader programs */ 318e5c31af7Sopenharmony_ci m_fs_po_id = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, /* count */ 319e5c31af7Sopenharmony_ci &fs_specialized_code_raw); 320e5c31af7Sopenharmony_ci m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */ 321e5c31af7Sopenharmony_ci &gs_specialized_code_raw); 322e5c31af7Sopenharmony_ci m_vs_po_id = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, /* count */ 323e5c31af7Sopenharmony_ci &vs_specialized_code_raw); 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call(s) failed."); 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci if (m_fs_po_id == 0 || m_gs_po_id == 0 || m_vs_po_id == 0) 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "At least one glCreateShaderProgramv() call returned 0." 330e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci result = false; 333e5c31af7Sopenharmony_ci goto end; 334e5c31af7Sopenharmony_ci } 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci /* Make sure all shader programs were linked successfully */ 337e5c31af7Sopenharmony_ci so_po_ids[0] = m_fs_po_id; 338e5c31af7Sopenharmony_ci so_po_ids[1] = m_gs_po_id; 339e5c31af7Sopenharmony_ci so_po_ids[2] = m_vs_po_id; 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci for (unsigned int n_po_id = 0; n_po_id != n_so_po_ids; ++n_po_id) 342e5c31af7Sopenharmony_ci { 343e5c31af7Sopenharmony_ci gl.getProgramiv(so_po_ids[n_po_id], GL_LINK_STATUS, &link_status); 344e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci if (link_status != GL_TRUE) 347e5c31af7Sopenharmony_ci { 348e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "A valid shader program with id [" << so_po_ids[n_po_id] 349e5c31af7Sopenharmony_ci << "] was not linked successfully." << tcu::TestLog::EndMessage; 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci result = false; 352e5c31af7Sopenharmony_ci goto end; 353e5c31af7Sopenharmony_ci } 354e5c31af7Sopenharmony_ci } 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci /* Set up the vertex array object */ 357e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 358e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 361e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci /* Set up the pipeline object */ 364e5c31af7Sopenharmony_ci initPipelineObject(); 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci /* Render a full-screen quad */ 367e5c31af7Sopenharmony_ci gl.bindProgramPipeline(m_pipeline_object_id); 368e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, /* first */ 371e5c31af7Sopenharmony_ci 1); /* count */ 372e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed."); 373e5c31af7Sopenharmony_ci 374e5c31af7Sopenharmony_ci /* Verify the rendering result */ 375e5c31af7Sopenharmony_ci unsigned char result_data[m_to_width * m_to_height * 4 /* rgba */]; 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci gl.readPixels(0, /* x */ 378e5c31af7Sopenharmony_ci 0, /* y */ 379e5c31af7Sopenharmony_ci m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, result_data); 380e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 381e5c31af7Sopenharmony_ci 382e5c31af7Sopenharmony_ci for (unsigned int y = 0; y < m_to_height; ++y) 383e5c31af7Sopenharmony_ci { 384e5c31af7Sopenharmony_ci unsigned char* traveller_ptr = result_data + 4 * y; 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci for (unsigned int x = 0; x < m_to_width; ++x) 387e5c31af7Sopenharmony_ci { 388e5c31af7Sopenharmony_ci if (traveller_ptr[0] != 0 || traveller_ptr[1] != 255 || traveller_ptr[2] != 0 || traveller_ptr[3] != 0) 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Invalid result texel found at (" << x << ", " << y 391e5c31af7Sopenharmony_ci << ")." << tcu::TestLog::EndMessage; 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ci result = false; 394e5c31af7Sopenharmony_ci } 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ci traveller_ptr += 4; /* rgba */ 397e5c31af7Sopenharmony_ci } 398e5c31af7Sopenharmony_ci } 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ciend: 401e5c31af7Sopenharmony_ci if (result) 402e5c31af7Sopenharmony_ci { 403e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 404e5c31af7Sopenharmony_ci } 405e5c31af7Sopenharmony_ci else 406e5c31af7Sopenharmony_ci { 407e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 408e5c31af7Sopenharmony_ci } 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci return STOP; 411e5c31af7Sopenharmony_ci} 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci/** Constructor 414e5c31af7Sopenharmony_ci * 415e5c31af7Sopenharmony_ci * @param context Test context 416e5c31af7Sopenharmony_ci * @param extParams Not used. 417e5c31af7Sopenharmony_ci * @param name Test case's name 418e5c31af7Sopenharmony_ci * @param description Test case's description 419e5c31af7Sopenharmony_ci **/ 420e5c31af7Sopenharmony_ciGeometryShaderGetShaderivTest::GeometryShaderGetShaderivTest(Context& context, const ExtParameters& extParams, 421e5c31af7Sopenharmony_ci const char* name, const char* description) 422e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_gs_id(0) 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_ci} 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 427e5c31af7Sopenharmony_civoid GeometryShaderGetShaderivTest::deinit() 428e5c31af7Sopenharmony_ci{ 429e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci if (m_gs_id != 0) 432e5c31af7Sopenharmony_ci { 433e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci m_gs_id = 0; 436e5c31af7Sopenharmony_ci } 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci /* Release base class */ 439e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 440e5c31af7Sopenharmony_ci} 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci/** Executes the test. 443e5c31af7Sopenharmony_ci * 444e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 445e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 446e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 447e5c31af7Sopenharmony_ci **/ 448e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderGetShaderivTest::iterate() 449e5c31af7Sopenharmony_ci{ 450e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 451e5c31af7Sopenharmony_ci bool result = true; 452e5c31af7Sopenharmony_ci 453e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 454e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 455e5c31af7Sopenharmony_ci { 456e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 457e5c31af7Sopenharmony_ci } 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci /* Create a GS */ 460e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed."); 463e5c31af7Sopenharmony_ci 464e5c31af7Sopenharmony_ci /* Check the type reported for the SO */ 465e5c31af7Sopenharmony_ci glw::GLint shader_type = GL_NONE; 466e5c31af7Sopenharmony_ci 467e5c31af7Sopenharmony_ci gl.getShaderiv(m_gs_id, GL_SHADER_TYPE, &shader_type); 468e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci if ((glw::GLenum)shader_type != m_glExtTokens.GEOMETRY_SHADER) 471e5c31af7Sopenharmony_ci { 472e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Invalid shader type [" << shader_type 473e5c31af7Sopenharmony_ci << "] reported for a Geometry Shader" << tcu::TestLog::EndMessage; 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci result = false; 476e5c31af7Sopenharmony_ci } 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci if (result) 479e5c31af7Sopenharmony_ci { 480e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 481e5c31af7Sopenharmony_ci } 482e5c31af7Sopenharmony_ci else 483e5c31af7Sopenharmony_ci { 484e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 485e5c31af7Sopenharmony_ci } 486e5c31af7Sopenharmony_ci 487e5c31af7Sopenharmony_ci return STOP; 488e5c31af7Sopenharmony_ci} 489e5c31af7Sopenharmony_ci 490e5c31af7Sopenharmony_ci/** Constructor 491e5c31af7Sopenharmony_ci * 492e5c31af7Sopenharmony_ci * @param context Test context 493e5c31af7Sopenharmony_ci * @param extParams Not used. 494e5c31af7Sopenharmony_ci * @param name Test case's name 495e5c31af7Sopenharmony_ci * @param description Test case's description 496e5c31af7Sopenharmony_ci **/ 497e5c31af7Sopenharmony_ciGeometryShaderGetProgramivTest::GeometryShaderGetProgramivTest(Context& context, const ExtParameters& extParams, 498e5c31af7Sopenharmony_ci const char* name, const char* description) 499e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_po_id(0) 500e5c31af7Sopenharmony_ci{ 501e5c31af7Sopenharmony_ci} 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 504e5c31af7Sopenharmony_civoid GeometryShaderGetProgramivTest::deinit() 505e5c31af7Sopenharmony_ci{ 506e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci if (m_po_id != 0) 509e5c31af7Sopenharmony_ci { 510e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 511e5c31af7Sopenharmony_ci 512e5c31af7Sopenharmony_ci m_po_id = 0; 513e5c31af7Sopenharmony_ci } 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci /* Release base class */ 516e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 517e5c31af7Sopenharmony_ci} 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci/** Executes the test. 520e5c31af7Sopenharmony_ci * 521e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 522e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 523e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 524e5c31af7Sopenharmony_ci **/ 525e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderGetProgramivTest::iterate() 526e5c31af7Sopenharmony_ci{ 527e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 528e5c31af7Sopenharmony_ci bool result = true; 529e5c31af7Sopenharmony_ci 530e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 531e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 532e5c31af7Sopenharmony_ci { 533e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 534e5c31af7Sopenharmony_ci } 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_ci /* Create a program object */ 537e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci /* Verify that GS-specific queries cause a GL_INVALID_OPERATION error */ 542e5c31af7Sopenharmony_ci const glw::GLenum pnames[] = { m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE, 543e5c31af7Sopenharmony_ci m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE, 544e5c31af7Sopenharmony_ci m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS }; 545e5c31af7Sopenharmony_ci const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]); 546e5c31af7Sopenharmony_ci 547e5c31af7Sopenharmony_ci for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname) 548e5c31af7Sopenharmony_ci { 549e5c31af7Sopenharmony_ci glw::GLenum error_code = GL_NO_ERROR; 550e5c31af7Sopenharmony_ci glw::GLenum pname = pnames[n_pname]; 551e5c31af7Sopenharmony_ci glw::GLint rv = -1; 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, pname, &rv); 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci error_code = gl.getError(); 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci if (error_code != GL_INVALID_OPERATION) 558e5c31af7Sopenharmony_ci { 559e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No error generated by glGetProgramiv() for pname [" << pname 560e5c31af7Sopenharmony_ci << "]" << tcu::TestLog::EndMessage; 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci result = false; 563e5c31af7Sopenharmony_ci } 564e5c31af7Sopenharmony_ci } /* for (all pnames) */ 565e5c31af7Sopenharmony_ci 566e5c31af7Sopenharmony_ci if (result) 567e5c31af7Sopenharmony_ci { 568e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 569e5c31af7Sopenharmony_ci } 570e5c31af7Sopenharmony_ci else 571e5c31af7Sopenharmony_ci { 572e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 573e5c31af7Sopenharmony_ci } 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci return STOP; 576e5c31af7Sopenharmony_ci} 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci/** Constructor 579e5c31af7Sopenharmony_ci * 580e5c31af7Sopenharmony_ci * @param context Test context 581e5c31af7Sopenharmony_ci * @param extParams Not used. 582e5c31af7Sopenharmony_ci * @param name Test case's name 583e5c31af7Sopenharmony_ci * @param description Test case's description 584e5c31af7Sopenharmony_ci **/ 585e5c31af7Sopenharmony_ciGeometryShaderGetProgramiv2Test::GeometryShaderGetProgramiv2Test(Context& context, const ExtParameters& extParams, 586e5c31af7Sopenharmony_ci const char* name, const char* description) 587e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_po_id(0), m_vs_id(0) 588e5c31af7Sopenharmony_ci{ 589e5c31af7Sopenharmony_ci} 590e5c31af7Sopenharmony_ci 591e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 592e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv2Test::deinit() 593e5c31af7Sopenharmony_ci{ 594e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci if (m_fs_id != 0) 597e5c31af7Sopenharmony_ci { 598e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci m_fs_id = 0; 601e5c31af7Sopenharmony_ci } 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci if (m_po_id != 0) 604e5c31af7Sopenharmony_ci { 605e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci m_po_id = 0; 608e5c31af7Sopenharmony_ci } 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci if (m_vs_id != 0) 611e5c31af7Sopenharmony_ci { 612e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 613e5c31af7Sopenharmony_ci 614e5c31af7Sopenharmony_ci m_vs_id = 0; 615e5c31af7Sopenharmony_ci } 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci /* Release base class */ 618e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 619e5c31af7Sopenharmony_ci} 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci/** Executes the test. 622e5c31af7Sopenharmony_ci * 623e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 624e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 625e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 626e5c31af7Sopenharmony_ci **/ 627e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderGetProgramiv2Test::iterate() 628e5c31af7Sopenharmony_ci{ 629e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 630e5c31af7Sopenharmony_ci const glw::GLenum pnames[] = { m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE, 631e5c31af7Sopenharmony_ci m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE, 632e5c31af7Sopenharmony_ci m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS }; 633e5c31af7Sopenharmony_ci const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]); 634e5c31af7Sopenharmony_ci bool result = true; 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 637e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 638e5c31af7Sopenharmony_ci { 639e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 640e5c31af7Sopenharmony_ci } 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ci /* Initialize the program object */ 643e5c31af7Sopenharmony_ci std::string specialized_minimal_fs = specializeShader(1, 644e5c31af7Sopenharmony_ci /* parts */ &minimal_fs_code); 645e5c31af7Sopenharmony_ci const char* specialized_minimal_fs_raw = specialized_minimal_fs.c_str(); 646e5c31af7Sopenharmony_ci std::string specialized_minimal_vs = specializeShader(1, 647e5c31af7Sopenharmony_ci /* parts */ &minimal_vs_code); 648e5c31af7Sopenharmony_ci const char* specialized_minimal_vs_raw = specialized_minimal_vs.c_str(); 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 651e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 656e5c31af7Sopenharmony_ci 657e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_fs_id, 1, &specialized_minimal_fs_raw, m_vs_id, 1, 660e5c31af7Sopenharmony_ci &specialized_minimal_vs_raw)) 661e5c31af7Sopenharmony_ci { 662e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build a minimal test program object" 663e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci result = false; 666e5c31af7Sopenharmony_ci goto end; 667e5c31af7Sopenharmony_ci } 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci /* Verify that GS-specific queries cause a GL_INVALID_OPERATION error 670e5c31af7Sopenharmony_ci * for a linked PO lacking the GS stage. 671e5c31af7Sopenharmony_ci */ 672e5c31af7Sopenharmony_ci for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname) 673e5c31af7Sopenharmony_ci { 674e5c31af7Sopenharmony_ci glw::GLenum error_code = GL_NO_ERROR; 675e5c31af7Sopenharmony_ci glw::GLenum pname = pnames[n_pname]; 676e5c31af7Sopenharmony_ci glw::GLint rv = -1; 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, pname, &rv); 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci error_code = gl.getError(); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci if (error_code != GL_INVALID_OPERATION) 683e5c31af7Sopenharmony_ci { 684e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "No error generated by glGetProgramiv() for pname [" << pname 685e5c31af7Sopenharmony_ci << "]" << tcu::TestLog::EndMessage; 686e5c31af7Sopenharmony_ci 687e5c31af7Sopenharmony_ci result = false; 688e5c31af7Sopenharmony_ci } 689e5c31af7Sopenharmony_ci } /* for (all pnames) */ 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ciend: 692e5c31af7Sopenharmony_ci if (result) 693e5c31af7Sopenharmony_ci { 694e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 695e5c31af7Sopenharmony_ci } 696e5c31af7Sopenharmony_ci else 697e5c31af7Sopenharmony_ci { 698e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 699e5c31af7Sopenharmony_ci } 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci return STOP; 702e5c31af7Sopenharmony_ci} 703e5c31af7Sopenharmony_ci 704e5c31af7Sopenharmony_ci/** Constructor 705e5c31af7Sopenharmony_ci * 706e5c31af7Sopenharmony_ci * @param context Test context 707e5c31af7Sopenharmony_ci * @param extParams Not used. 708e5c31af7Sopenharmony_ci * @param name Test case's name 709e5c31af7Sopenharmony_ci * @param description Test case's description 710e5c31af7Sopenharmony_ci **/ 711e5c31af7Sopenharmony_ciGeometryShaderGetProgramiv3Test::GeometryShaderGetProgramiv3Test(Context& context, const ExtParameters& extParams, 712e5c31af7Sopenharmony_ci const char* name, const char* description) 713e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 714e5c31af7Sopenharmony_ci , m_fs_id(0) 715e5c31af7Sopenharmony_ci , m_fs_po_id(0) 716e5c31af7Sopenharmony_ci , m_gs_id(0) 717e5c31af7Sopenharmony_ci , m_gs_po_id(0) 718e5c31af7Sopenharmony_ci , m_pipeline_object_id(0) 719e5c31af7Sopenharmony_ci , m_po_id(0) 720e5c31af7Sopenharmony_ci , m_vs_id(0) 721e5c31af7Sopenharmony_ci , m_vs_po_id(0) 722e5c31af7Sopenharmony_ci{ 723e5c31af7Sopenharmony_ci} 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci/* Compiles a shader object using caller-specified data. 726e5c31af7Sopenharmony_ci * 727e5c31af7Sopenharmony_ci * @param so_id ID of a Shader Object to compile. 728e5c31af7Sopenharmony_ci * @param so_body Body to use for the compilation process. 729e5c31af7Sopenharmony_ci * 730e5c31af7Sopenharmony_ci * @return true if the compilation succeeded, false otherwise */ 731e5c31af7Sopenharmony_cibool GeometryShaderGetProgramiv3Test::buildShader(glw::GLuint so_id, const char* so_body) 732e5c31af7Sopenharmony_ci{ 733e5c31af7Sopenharmony_ci glw::GLint compile_status = GL_FALSE; 734e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 735e5c31af7Sopenharmony_ci bool result = false; 736e5c31af7Sopenharmony_ci 737e5c31af7Sopenharmony_ci gl.shaderSource(so_id, 1, /* count */ 738e5c31af7Sopenharmony_ci &so_body, DE_NULL); /* length */ 739e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed."); 740e5c31af7Sopenharmony_ci 741e5c31af7Sopenharmony_ci gl.compileShader(so_id); 742e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed."); 743e5c31af7Sopenharmony_ci 744e5c31af7Sopenharmony_ci gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status); 745e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed."); 746e5c31af7Sopenharmony_ci 747e5c31af7Sopenharmony_ci result = (compile_status == GL_TRUE); 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_ci return result; 750e5c31af7Sopenharmony_ci} 751e5c31af7Sopenharmony_ci 752e5c31af7Sopenharmony_ci/** Builds a single shader program object using caller-specified data. 753e5c31af7Sopenharmony_ci * 754e5c31af7Sopenharmony_ci * @param out_spo_id Deref will be set to the ID of the created shader program object. 755e5c31af7Sopenharmony_ci * Must not be NULL. 756e5c31af7Sopenharmony_ci * @param spo_bits Bits to be passed to the glCreateShaderProgramv() call. 757e5c31af7Sopenharmony_ci * @param spo_body Body to use for the glCreateShaderProgramv() call. 758e5c31af7Sopenharmony_ci * 759e5c31af7Sopenharmony_ci * @return true if the shader program object was linked successfully, false otherwise. 760e5c31af7Sopenharmony_ci */ 761e5c31af7Sopenharmony_cibool GeometryShaderGetProgramiv3Test::buildShaderProgram(glw::GLuint* out_spo_id, glw::GLenum spo_bits, 762e5c31af7Sopenharmony_ci const char* spo_body) 763e5c31af7Sopenharmony_ci{ 764e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 765e5c31af7Sopenharmony_ci glw::GLint link_status = GL_FALSE; 766e5c31af7Sopenharmony_ci bool result = true; 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci *out_spo_id = gl.createShaderProgramv(spo_bits, 1, /* count */ 769e5c31af7Sopenharmony_ci &spo_body); 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed."); 772e5c31af7Sopenharmony_ci 773e5c31af7Sopenharmony_ci gl.getProgramiv(*out_spo_id, GL_LINK_STATUS, &link_status); 774e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed."); 775e5c31af7Sopenharmony_ci 776e5c31af7Sopenharmony_ci result = (link_status == GL_TRUE); 777e5c31af7Sopenharmony_ci 778e5c31af7Sopenharmony_ci return result; 779e5c31af7Sopenharmony_ci} 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 782e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv3Test::deinit() 783e5c31af7Sopenharmony_ci{ 784e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 785e5c31af7Sopenharmony_ci 786e5c31af7Sopenharmony_ci deinitPO(); 787e5c31af7Sopenharmony_ci deinitSOs(true); 788e5c31af7Sopenharmony_ci deinitSPOs(true); 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_ci if (m_pipeline_object_id != 0) 791e5c31af7Sopenharmony_ci { 792e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_pipeline_object_id); 793e5c31af7Sopenharmony_ci 794e5c31af7Sopenharmony_ci m_pipeline_object_id = 0; 795e5c31af7Sopenharmony_ci } 796e5c31af7Sopenharmony_ci 797e5c31af7Sopenharmony_ci /* Release base class */ 798e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 799e5c31af7Sopenharmony_ci} 800e5c31af7Sopenharmony_ci 801e5c31af7Sopenharmony_ci/** Deinitializes a program object created for the conformance test. */ 802e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv3Test::deinitPO() 803e5c31af7Sopenharmony_ci{ 804e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 805e5c31af7Sopenharmony_ci 806e5c31af7Sopenharmony_ci if (m_po_id != 0) 807e5c31af7Sopenharmony_ci { 808e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 809e5c31af7Sopenharmony_ci 810e5c31af7Sopenharmony_ci m_po_id = 0; 811e5c31af7Sopenharmony_ci } 812e5c31af7Sopenharmony_ci} 813e5c31af7Sopenharmony_ci 814e5c31af7Sopenharmony_ci/** Deinitializes shader objects created for the conformance test. */ 815e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv3Test::deinitSOs(bool release_all_SOs) 816e5c31af7Sopenharmony_ci{ 817e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ci if (m_fs_id != 0 && release_all_SOs) 820e5c31af7Sopenharmony_ci { 821e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 822e5c31af7Sopenharmony_ci 823e5c31af7Sopenharmony_ci m_fs_id = 0; 824e5c31af7Sopenharmony_ci } 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci if (m_gs_id != 0) 827e5c31af7Sopenharmony_ci { 828e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci m_gs_id = 0; 831e5c31af7Sopenharmony_ci } 832e5c31af7Sopenharmony_ci 833e5c31af7Sopenharmony_ci if (m_vs_id != 0 && release_all_SOs) 834e5c31af7Sopenharmony_ci { 835e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 836e5c31af7Sopenharmony_ci 837e5c31af7Sopenharmony_ci m_vs_id = 0; 838e5c31af7Sopenharmony_ci } 839e5c31af7Sopenharmony_ci} 840e5c31af7Sopenharmony_ci 841e5c31af7Sopenharmony_ci/** Deinitializes shader program objects created for the conformance test. */ 842e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv3Test::deinitSPOs(bool release_all_SPOs) 843e5c31af7Sopenharmony_ci{ 844e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 845e5c31af7Sopenharmony_ci 846e5c31af7Sopenharmony_ci if (m_fs_po_id != 0 && release_all_SPOs) 847e5c31af7Sopenharmony_ci { 848e5c31af7Sopenharmony_ci gl.deleteProgram(m_fs_po_id); 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci m_fs_po_id = 0; 851e5c31af7Sopenharmony_ci } 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci if (m_gs_po_id != 0) 854e5c31af7Sopenharmony_ci { 855e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_ci m_gs_po_id = 0; 858e5c31af7Sopenharmony_ci } 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci if (m_vs_po_id != 0 && release_all_SPOs) 861e5c31af7Sopenharmony_ci { 862e5c31af7Sopenharmony_ci gl.deleteProgram(m_vs_po_id); 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci m_vs_po_id = 0; 865e5c31af7Sopenharmony_ci } 866e5c31af7Sopenharmony_ci} 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ci/** Retrieves ES SL layout qualifier, corresponding to user-specified 869e5c31af7Sopenharmony_ci * primitive type. 870e5c31af7Sopenharmony_ci * 871e5c31af7Sopenharmony_ci * @param primitive_type Primitive type (described by a GLenum value) 872e5c31af7Sopenharmony_ci * to use for the query. 873e5c31af7Sopenharmony_ci * 874e5c31af7Sopenharmony_ci * @return Requested layout qualifier. 875e5c31af7Sopenharmony_ci */ 876e5c31af7Sopenharmony_cistd::string GeometryShaderGetProgramiv3Test::getLayoutQualifierForPrimitiveType(glw::GLenum primitive_type) 877e5c31af7Sopenharmony_ci{ 878e5c31af7Sopenharmony_ci std::string result; 879e5c31af7Sopenharmony_ci 880e5c31af7Sopenharmony_ci switch (primitive_type) 881e5c31af7Sopenharmony_ci { 882e5c31af7Sopenharmony_ci case GL_LINE_STRIP: 883e5c31af7Sopenharmony_ci result = "line_strip"; 884e5c31af7Sopenharmony_ci break; 885e5c31af7Sopenharmony_ci case GL_LINES_ADJACENCY: 886e5c31af7Sopenharmony_ci result = "lines_adjacency"; 887e5c31af7Sopenharmony_ci break; 888e5c31af7Sopenharmony_ci case GL_POINTS: 889e5c31af7Sopenharmony_ci result = "points"; 890e5c31af7Sopenharmony_ci break; 891e5c31af7Sopenharmony_ci case GL_TRIANGLES: 892e5c31af7Sopenharmony_ci result = "triangles"; 893e5c31af7Sopenharmony_ci break; 894e5c31af7Sopenharmony_ci case GL_TRIANGLE_STRIP: 895e5c31af7Sopenharmony_ci result = "triangle_strip"; 896e5c31af7Sopenharmony_ci break; 897e5c31af7Sopenharmony_ci 898e5c31af7Sopenharmony_ci default: 899e5c31af7Sopenharmony_ci { 900e5c31af7Sopenharmony_ci DE_ASSERT(0); 901e5c31af7Sopenharmony_ci } 902e5c31af7Sopenharmony_ci } /* switch (primitive_type) */ 903e5c31af7Sopenharmony_ci 904e5c31af7Sopenharmony_ci return result; 905e5c31af7Sopenharmony_ci} 906e5c31af7Sopenharmony_ci 907e5c31af7Sopenharmony_ci/** Retrieves body of a geometry shadet to be used for the conformance test. 908e5c31af7Sopenharmony_ci * The body is generated, according to the properties described by the 909e5c31af7Sopenharmony_ci * run descriptor passed as an argument. 910e5c31af7Sopenharmony_ci * 911e5c31af7Sopenharmony_ci * @param run Test run descriptor. 912e5c31af7Sopenharmony_ci * 913e5c31af7Sopenharmony_ci * @return Requested string. 914e5c31af7Sopenharmony_ci */ 915e5c31af7Sopenharmony_cistd::string GeometryShaderGetProgramiv3Test::getGSCode(const _run& run) 916e5c31af7Sopenharmony_ci{ 917e5c31af7Sopenharmony_ci std::stringstream code_sstream; 918e5c31af7Sopenharmony_ci 919e5c31af7Sopenharmony_ci code_sstream << "${VERSION}\n" 920e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 921e5c31af7Sopenharmony_ci "\n" 922e5c31af7Sopenharmony_ci "layout(" 923e5c31af7Sopenharmony_ci << getLayoutQualifierForPrimitiveType(run.input_primitive_type) << ", " 924e5c31af7Sopenharmony_ci "invocations = " 925e5c31af7Sopenharmony_ci << run.invocations << ") in;\n" 926e5c31af7Sopenharmony_ci "layout(" 927e5c31af7Sopenharmony_ci << getLayoutQualifierForPrimitiveType(run.output_primitive_type) << ", " 928e5c31af7Sopenharmony_ci "max_vertices = " 929e5c31af7Sopenharmony_ci << run.max_vertices << ") out;\n" 930e5c31af7Sopenharmony_ci "\n" 931e5c31af7Sopenharmony_ci "out gl_PerVertex {\n" 932e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 933e5c31af7Sopenharmony_ci "};\n" 934e5c31af7Sopenharmony_ci "\n" 935e5c31af7Sopenharmony_ci "void main()\n" 936e5c31af7Sopenharmony_ci "{\n" 937e5c31af7Sopenharmony_ci " for (int n = 0; n < " 938e5c31af7Sopenharmony_ci << run.max_vertices << "; ++n)\n" 939e5c31af7Sopenharmony_ci " {\n" 940e5c31af7Sopenharmony_ci " gl_Position = vec4(n, 0.0, 0.0, 1.0);\n" 941e5c31af7Sopenharmony_ci " EmitVertex();\n" 942e5c31af7Sopenharmony_ci " }\n" 943e5c31af7Sopenharmony_ci "\n" 944e5c31af7Sopenharmony_ci " EndPrimitive();\n" 945e5c31af7Sopenharmony_ci "}\n"; 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci return code_sstream.str(); 948e5c31af7Sopenharmony_ci} 949e5c31af7Sopenharmony_ci 950e5c31af7Sopenharmony_ci/** Initializes internal _runs member with test iteration settings for all test runs. */ 951e5c31af7Sopenharmony_civoid GeometryShaderGetProgramiv3Test::initTestRuns() 952e5c31af7Sopenharmony_ci{ 953e5c31af7Sopenharmony_ci /* input primitive type | invocations | max vertices | output primitive type * 954e5c31af7Sopenharmony_ci *----------------------------------------+-------------+--------------+-----------------------*/ 955e5c31af7Sopenharmony_ci _runs.push_back(_run(GL_LINES_ADJACENCY, 3, 16, GL_POINTS)); 956e5c31af7Sopenharmony_ci _runs.push_back(_run(GL_TRIANGLES, 12, 37, GL_LINE_STRIP)); 957e5c31af7Sopenharmony_ci _runs.push_back(_run(GL_POINTS, 31, 75, GL_TRIANGLE_STRIP)); 958e5c31af7Sopenharmony_ci} 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_ci/** Executes the test. 961e5c31af7Sopenharmony_ci * 962e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 963e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 964e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 965e5c31af7Sopenharmony_ci **/ 966e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderGetProgramiv3Test::iterate() 967e5c31af7Sopenharmony_ci{ 968e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 969e5c31af7Sopenharmony_ci glw::GLint gs_spo_id = 0; 970e5c31af7Sopenharmony_ci unsigned int n_run = 0; 971e5c31af7Sopenharmony_ci unsigned int n_separable_object_case = 0; 972e5c31af7Sopenharmony_ci bool result = true; 973e5c31af7Sopenharmony_ci 974e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 975e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 976e5c31af7Sopenharmony_ci { 977e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 978e5c31af7Sopenharmony_ci } 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_ci /* Prepare specialized versions of minimal fragment & vertex shaders */ 981e5c31af7Sopenharmony_ci std::string minimal_fs_specialized = specializeShader(1, 982e5c31af7Sopenharmony_ci /* parts */ &minimal_fs_code); 983e5c31af7Sopenharmony_ci const char* minimal_fs_specialized_raw = minimal_fs_specialized.c_str(); 984e5c31af7Sopenharmony_ci std::string minimal_vs_specialized = specializeShader(1, &minimal_vs_code); 985e5c31af7Sopenharmony_ci const char* minimal_vs_specialized_raw = minimal_vs_specialized.c_str(); 986e5c31af7Sopenharmony_ci 987e5c31af7Sopenharmony_ci /* Set up the fragment & the vertex shaders */ 988e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 989e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 990e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci if (!buildShader(m_fs_id, minimal_fs_specialized_raw) || !buildShader(m_vs_id, minimal_vs_specialized_raw)) 995e5c31af7Sopenharmony_ci { 996e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Either FS or VS failed to build." << tcu::TestLog::EndMessage; 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci result = false; 999e5c31af7Sopenharmony_ci goto end; 1000e5c31af7Sopenharmony_ci } 1001e5c31af7Sopenharmony_ci 1002e5c31af7Sopenharmony_ci /* Set up the test program object */ 1003e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 1006e5c31af7Sopenharmony_ci 1007e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_fs_id); 1008e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_gs_id); 1009e5c31af7Sopenharmony_ci gl.attachShader(m_po_id, m_vs_id); 1010e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed."); 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci /* Set up the fragment & the vertex shader programs */ 1013e5c31af7Sopenharmony_ci if (!buildShaderProgram(&m_fs_po_id, GL_FRAGMENT_SHADER, minimal_fs_specialized_raw) || 1014e5c31af7Sopenharmony_ci !buildShaderProgram(&m_vs_po_id, GL_VERTEX_SHADER, minimal_vs_specialized_raw)) 1015e5c31af7Sopenharmony_ci { 1016e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Either FS or VS SPOs failed to build." 1017e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_ci result = false; 1020e5c31af7Sopenharmony_ci goto end; 1021e5c31af7Sopenharmony_ci } 1022e5c31af7Sopenharmony_ci 1023e5c31af7Sopenharmony_ci /* Set up test runs */ 1024e5c31af7Sopenharmony_ci initTestRuns(); 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci /* The test should check both a geometry shader program object and a full-blown PO 1027e5c31af7Sopenharmony_ci * consisting of FS, GS and VS. */ 1028e5c31af7Sopenharmony_ci for (n_separable_object_case = 0; n_separable_object_case < 2; /* PO, SPO cases */ 1029e5c31af7Sopenharmony_ci ++n_separable_object_case) 1030e5c31af7Sopenharmony_ci { 1031e5c31af7Sopenharmony_ci bool should_use_separable_object = (n_separable_object_case != 0); 1032e5c31af7Sopenharmony_ci 1033e5c31af7Sopenharmony_ci /* Iterate over all test runs */ 1034e5c31af7Sopenharmony_ci for (n_run = 0; n_run < _runs.size(); ++n_run) 1035e5c31af7Sopenharmony_ci { 1036e5c31af7Sopenharmony_ci const _run& current_run = _runs[n_run]; 1037e5c31af7Sopenharmony_ci std::string gs_code = getGSCode(current_run); 1038e5c31af7Sopenharmony_ci const char* gs_code_raw = gs_code.c_str(); 1039e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, /* parts */ 1040e5c31af7Sopenharmony_ci &gs_code_raw); 1041e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = gs_code_specialized.c_str(); 1042e5c31af7Sopenharmony_ci 1043e5c31af7Sopenharmony_ci if (should_use_separable_object) 1044e5c31af7Sopenharmony_ci { 1045e5c31af7Sopenharmony_ci /* Deinitialize any objects that may have been created in previous iterations */ 1046e5c31af7Sopenharmony_ci deinitSPOs(false); 1047e5c31af7Sopenharmony_ci 1048e5c31af7Sopenharmony_ci /* Set up the geometry shader program object */ 1049e5c31af7Sopenharmony_ci if (!buildShaderProgram(&m_gs_po_id, GL_GEOMETRY_SHADER, gs_code_specialized_raw)) 1050e5c31af7Sopenharmony_ci { 1051e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Failed to compile a geometry shader program object" 1052e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci result = false; 1055e5c31af7Sopenharmony_ci goto end; 1056e5c31af7Sopenharmony_ci } 1057e5c31af7Sopenharmony_ci } /* if (should_use_pipeline_object) */ 1058e5c31af7Sopenharmony_ci else 1059e5c31af7Sopenharmony_ci { 1060e5c31af7Sopenharmony_ci gl.bindProgramPipeline(0); 1061e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 1062e5c31af7Sopenharmony_ci 1063e5c31af7Sopenharmony_ci /* Set up the geometry shader object */ 1064e5c31af7Sopenharmony_ci if (!buildShader(m_gs_id, gs_code_specialized_raw)) 1065e5c31af7Sopenharmony_ci { 1066e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Failed to compile a geometry shader object." 1067e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1068e5c31af7Sopenharmony_ci 1069e5c31af7Sopenharmony_ci result = false; 1070e5c31af7Sopenharmony_ci goto end; 1071e5c31af7Sopenharmony_ci } 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci /* Set up the program object */ 1074e5c31af7Sopenharmony_ci glw::GLint link_status = GL_FALSE; 1075e5c31af7Sopenharmony_ci 1076e5c31af7Sopenharmony_ci gl.linkProgram(m_po_id); 1077e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed."); 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_ci gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status); 1080e5c31af7Sopenharmony_ci 1081e5c31af7Sopenharmony_ci if (link_status == GL_FALSE) 1082e5c31af7Sopenharmony_ci { 1083e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Test program object failed to link" 1084e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1085e5c31af7Sopenharmony_ci 1086e5c31af7Sopenharmony_ci result = false; 1087e5c31af7Sopenharmony_ci goto end; 1088e5c31af7Sopenharmony_ci } 1089e5c31af7Sopenharmony_ci 1090e5c31af7Sopenharmony_ci /* Bind the PO to the rendering context */ 1091e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 1092e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1093e5c31af7Sopenharmony_ci } 1094e5c31af7Sopenharmony_ci 1095e5c31af7Sopenharmony_ci /* Execute the queries */ 1096e5c31af7Sopenharmony_ci glw::GLuint po_id = (should_use_separable_object) ? m_gs_po_id : m_po_id; 1097e5c31af7Sopenharmony_ci glw::GLint result_geometry_linked_vertices_out = 0; 1098e5c31af7Sopenharmony_ci glw::GLint result_geometry_linked_input_type = 0; 1099e5c31af7Sopenharmony_ci glw::GLint result_geometry_linked_output_type = 0; 1100e5c31af7Sopenharmony_ci glw::GLint result_geometry_shader_invocations = 0; 1101e5c31af7Sopenharmony_ci 1102e5c31af7Sopenharmony_ci gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, &result_geometry_linked_vertices_out); 1103e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 1104e5c31af7Sopenharmony_ci "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_VERTICES_OUT_EXT query."); 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE, &result_geometry_linked_input_type); 1107e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 1108e5c31af7Sopenharmony_ci "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query."); 1109e5c31af7Sopenharmony_ci 1110e5c31af7Sopenharmony_ci gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE, &result_geometry_linked_output_type); 1111e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 1112e5c31af7Sopenharmony_ci "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT query."); 1113e5c31af7Sopenharmony_ci 1114e5c31af7Sopenharmony_ci gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS, &result_geometry_shader_invocations); 1115e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 1116e5c31af7Sopenharmony_ci "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query."); 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci if (current_run.input_primitive_type != (glw::GLenum)result_geometry_linked_input_type) 1119e5c31af7Sopenharmony_ci { 1120e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query value " 1121e5c31af7Sopenharmony_ci << "[" << result_geometry_linked_input_type 1122e5c31af7Sopenharmony_ci << "]" 1123e5c31af7Sopenharmony_ci " does not match the test run setting " 1124e5c31af7Sopenharmony_ci "[" 1125e5c31af7Sopenharmony_ci << current_run.input_primitive_type << "]" << tcu::TestLog::EndMessage; 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ci result = false; 1128e5c31af7Sopenharmony_ci } 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci if (current_run.invocations != result_geometry_shader_invocations) 1131e5c31af7Sopenharmony_ci { 1132e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_SHADER_INVOCATIONS_EXT query value " 1133e5c31af7Sopenharmony_ci << "[" << result_geometry_shader_invocations 1134e5c31af7Sopenharmony_ci << "]" 1135e5c31af7Sopenharmony_ci " does not match the test run setting " 1136e5c31af7Sopenharmony_ci "[" 1137e5c31af7Sopenharmony_ci << current_run.input_primitive_type << "]" << tcu::TestLog::EndMessage; 1138e5c31af7Sopenharmony_ci 1139e5c31af7Sopenharmony_ci result = false; 1140e5c31af7Sopenharmony_ci } 1141e5c31af7Sopenharmony_ci 1142e5c31af7Sopenharmony_ci if (current_run.max_vertices != result_geometry_linked_vertices_out) 1143e5c31af7Sopenharmony_ci { 1144e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_VERTICES_OUT query value " 1145e5c31af7Sopenharmony_ci << "[" << result_geometry_linked_vertices_out 1146e5c31af7Sopenharmony_ci << "]" 1147e5c31af7Sopenharmony_ci " does not match the test run setting " 1148e5c31af7Sopenharmony_ci "[" 1149e5c31af7Sopenharmony_ci << current_run.max_vertices << "]" << tcu::TestLog::EndMessage; 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci result = false; 1152e5c31af7Sopenharmony_ci } 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci if (current_run.output_primitive_type != (glw::GLenum)result_geometry_linked_output_type) 1155e5c31af7Sopenharmony_ci { 1156e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT query value " 1157e5c31af7Sopenharmony_ci << "[" << result_geometry_linked_output_type 1158e5c31af7Sopenharmony_ci << "]" 1159e5c31af7Sopenharmony_ci " does not match the test run setting " 1160e5c31af7Sopenharmony_ci "[" 1161e5c31af7Sopenharmony_ci << current_run.output_primitive_type << "]" << tcu::TestLog::EndMessage; 1162e5c31af7Sopenharmony_ci 1163e5c31af7Sopenharmony_ci result = false; 1164e5c31af7Sopenharmony_ci } 1165e5c31af7Sopenharmony_ci } /* for (all test runs) */ 1166e5c31af7Sopenharmony_ci } /* for (PO & SPO cases) */ 1167e5c31af7Sopenharmony_ci 1168e5c31af7Sopenharmony_ci /* One more check: build a pipeline object which only defines a FS & VS stages, 1169e5c31af7Sopenharmony_ci * and check what GS SPO ID the object reports. */ 1170e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &m_pipeline_object_id); 1171e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 1172e5c31af7Sopenharmony_ci 1173e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id); 1174e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_VERTEX_SHADER_BIT, m_vs_po_id); 1175e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 1176e5c31af7Sopenharmony_ci 1177e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(m_pipeline_object_id, m_glExtTokens.GEOMETRY_SHADER, &gs_spo_id); 1178e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed."); 1179e5c31af7Sopenharmony_ci 1180e5c31af7Sopenharmony_ci if (gs_spo_id != 0) 1181e5c31af7Sopenharmony_ci { 1182e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Pipeline object reported [" << gs_spo_id << "]" 1183e5c31af7Sopenharmony_ci << " for GL_GEOMETRY_SHADER_EXT query, even though no GS SPO was bound." 1184e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1185e5c31af7Sopenharmony_ci 1186e5c31af7Sopenharmony_ci result = false; 1187e5c31af7Sopenharmony_ci } 1188e5c31af7Sopenharmony_ci 1189e5c31af7Sopenharmony_ciend: 1190e5c31af7Sopenharmony_ci if (result) 1191e5c31af7Sopenharmony_ci { 1192e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1193e5c31af7Sopenharmony_ci } 1194e5c31af7Sopenharmony_ci else 1195e5c31af7Sopenharmony_ci { 1196e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1197e5c31af7Sopenharmony_ci } 1198e5c31af7Sopenharmony_ci 1199e5c31af7Sopenharmony_ci return STOP; 1200e5c31af7Sopenharmony_ci} 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ci/** Constructor 1203e5c31af7Sopenharmony_ci * 1204e5c31af7Sopenharmony_ci * @param context Test context 1205e5c31af7Sopenharmony_ci * @param extParams Not used. 1206e5c31af7Sopenharmony_ci * @param name Test case's name 1207e5c31af7Sopenharmony_ci * @param description Test case's description 1208e5c31af7Sopenharmony_ci **/ 1209e5c31af7Sopenharmony_ciGeometryShaderDrawCallWithFSAndGS::GeometryShaderDrawCallWithFSAndGS(Context& context, const ExtParameters& extParams, 1210e5c31af7Sopenharmony_ci const char* name, const char* description) 1211e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 1212e5c31af7Sopenharmony_ci , m_fs_po_id(0) 1213e5c31af7Sopenharmony_ci , m_gs_po_id(0) 1214e5c31af7Sopenharmony_ci , m_pipeline_object_id(0) 1215e5c31af7Sopenharmony_ci , m_vao_id(0) 1216e5c31af7Sopenharmony_ci{ 1217e5c31af7Sopenharmony_ci} 1218e5c31af7Sopenharmony_ci 1219e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 1220e5c31af7Sopenharmony_civoid GeometryShaderDrawCallWithFSAndGS::deinit() 1221e5c31af7Sopenharmony_ci{ 1222e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1223e5c31af7Sopenharmony_ci 1224e5c31af7Sopenharmony_ci if (m_fs_po_id != 0) 1225e5c31af7Sopenharmony_ci { 1226e5c31af7Sopenharmony_ci gl.deleteProgram(m_fs_po_id); 1227e5c31af7Sopenharmony_ci 1228e5c31af7Sopenharmony_ci m_fs_po_id = 0; 1229e5c31af7Sopenharmony_ci } 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_ci if (m_gs_po_id != 0) 1232e5c31af7Sopenharmony_ci { 1233e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci m_gs_po_id = 0; 1236e5c31af7Sopenharmony_ci } 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci if (m_pipeline_object_id != 0) 1239e5c31af7Sopenharmony_ci { 1240e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_pipeline_object_id); 1241e5c31af7Sopenharmony_ci 1242e5c31af7Sopenharmony_ci m_pipeline_object_id = 0; 1243e5c31af7Sopenharmony_ci } 1244e5c31af7Sopenharmony_ci 1245e5c31af7Sopenharmony_ci if (m_vao_id != 0) 1246e5c31af7Sopenharmony_ci { 1247e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci m_vao_id = 0; 1250e5c31af7Sopenharmony_ci } 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci /* Release base class */ 1253e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 1254e5c31af7Sopenharmony_ci} 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci/** Executes the test. 1257e5c31af7Sopenharmony_ci * 1258e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1259e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 1260e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 1261e5c31af7Sopenharmony_ci **/ 1262e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderDrawCallWithFSAndGS::iterate() 1263e5c31af7Sopenharmony_ci{ 1264e5c31af7Sopenharmony_ci glw::GLenum error_code = GL_NO_ERROR; 1265e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1266e5c31af7Sopenharmony_ci bool result = true; 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 1269e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 1270e5c31af7Sopenharmony_ci { 1271e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1272e5c31af7Sopenharmony_ci } 1273e5c31af7Sopenharmony_ci 1274e5c31af7Sopenharmony_ci /* Create & bind a VAO */ 1275e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 1276e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 1277e5c31af7Sopenharmony_ci 1278e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 1279e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 1280e5c31af7Sopenharmony_ci 1281e5c31af7Sopenharmony_ci /* Create shader program objects */ 1282e5c31af7Sopenharmony_ci std::string code_fs_specialized = specializeShader(1, /* parts */ 1283e5c31af7Sopenharmony_ci &minimal_fs_code); 1284e5c31af7Sopenharmony_ci const char* code_fs_specialized_raw = code_fs_specialized.c_str(); 1285e5c31af7Sopenharmony_ci std::string code_gs_specialized = specializeShader(1, /* parts */ 1286e5c31af7Sopenharmony_ci &minimal_gs_code); 1287e5c31af7Sopenharmony_ci const char* code_gs_specialized_raw = code_gs_specialized.c_str(); 1288e5c31af7Sopenharmony_ci glw::GLint link_status = GL_FALSE; 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci m_fs_po_id = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, /* count */ 1291e5c31af7Sopenharmony_ci &code_fs_specialized_raw); 1292e5c31af7Sopenharmony_ci m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */ 1293e5c31af7Sopenharmony_ci &code_gs_specialized_raw); 1294e5c31af7Sopenharmony_ci 1295e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call(s) failed."); 1296e5c31af7Sopenharmony_ci 1297e5c31af7Sopenharmony_ci gl.getProgramiv(m_fs_po_id, GL_LINK_STATUS, &link_status); 1298e5c31af7Sopenharmony_ci 1299e5c31af7Sopenharmony_ci if (link_status != GL_TRUE) 1300e5c31af7Sopenharmony_ci { 1301e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Minimal fragment shader program failed to link." 1302e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1303e5c31af7Sopenharmony_ci 1304e5c31af7Sopenharmony_ci result = false; 1305e5c31af7Sopenharmony_ci goto end; 1306e5c31af7Sopenharmony_ci } 1307e5c31af7Sopenharmony_ci 1308e5c31af7Sopenharmony_ci gl.getProgramiv(m_gs_po_id, GL_LINK_STATUS, &link_status); 1309e5c31af7Sopenharmony_ci 1310e5c31af7Sopenharmony_ci if (link_status != GL_TRUE) 1311e5c31af7Sopenharmony_ci { 1312e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Minimal geometry shader program failed to link." 1313e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1314e5c31af7Sopenharmony_ci 1315e5c31af7Sopenharmony_ci result = false; 1316e5c31af7Sopenharmony_ci goto end; 1317e5c31af7Sopenharmony_ci } 1318e5c31af7Sopenharmony_ci 1319e5c31af7Sopenharmony_ci /* Create & set up a pipeline object */ 1320e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &m_pipeline_object_id); 1321e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 1322e5c31af7Sopenharmony_ci 1323e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id); 1324e5c31af7Sopenharmony_ci gl.useProgramStages(m_pipeline_object_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id); 1325e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed."); 1326e5c31af7Sopenharmony_ci 1327e5c31af7Sopenharmony_ci gl.bindProgramPipeline(m_pipeline_object_id); 1328e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_ci /* Try to do a draw call */ 1331e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, /* first */ 1332e5c31af7Sopenharmony_ci 1); /* count */ 1333e5c31af7Sopenharmony_ci 1334e5c31af7Sopenharmony_ci error_code = gl.getError(); 1335e5c31af7Sopenharmony_ci if (error_code != GL_INVALID_OPERATION) 1336e5c31af7Sopenharmony_ci { 1337e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Invalid draw call generated an error code [" << error_code 1338e5c31af7Sopenharmony_ci << "]" 1339e5c31af7Sopenharmony_ci " which is different from the expected GL_INVALID_OPERATION." 1340e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1341e5c31af7Sopenharmony_ci 1342e5c31af7Sopenharmony_ci result = false; 1343e5c31af7Sopenharmony_ci } 1344e5c31af7Sopenharmony_ci 1345e5c31af7Sopenharmony_ciend: 1346e5c31af7Sopenharmony_ci // m_pipeline_object_id is generated in this function, need to be freed 1347e5c31af7Sopenharmony_ci if (m_pipeline_object_id) 1348e5c31af7Sopenharmony_ci { 1349e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_pipeline_object_id); 1350e5c31af7Sopenharmony_ci m_pipeline_object_id = 0; 1351e5c31af7Sopenharmony_ci } 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_ci // m_gs_po_id is generated in this function, need to be freed 1354e5c31af7Sopenharmony_ci if (m_gs_po_id) 1355e5c31af7Sopenharmony_ci { 1356e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 1357e5c31af7Sopenharmony_ci m_gs_po_id = 0; 1358e5c31af7Sopenharmony_ci } 1359e5c31af7Sopenharmony_ci 1360e5c31af7Sopenharmony_ci // m_fs_po_id is generated in this function, need to be freed 1361e5c31af7Sopenharmony_ci if (m_fs_po_id) 1362e5c31af7Sopenharmony_ci { 1363e5c31af7Sopenharmony_ci gl.deleteProgram(m_fs_po_id); 1364e5c31af7Sopenharmony_ci m_fs_po_id = 0; 1365e5c31af7Sopenharmony_ci } 1366e5c31af7Sopenharmony_ci 1367e5c31af7Sopenharmony_ci // m_vao_id is generated in this function, need to be freed 1368e5c31af7Sopenharmony_ci if (m_vao_id) 1369e5c31af7Sopenharmony_ci { 1370e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 1371e5c31af7Sopenharmony_ci m_vao_id = 0; 1372e5c31af7Sopenharmony_ci } 1373e5c31af7Sopenharmony_ci 1374e5c31af7Sopenharmony_ci /* All done */ 1375e5c31af7Sopenharmony_ci if (result) 1376e5c31af7Sopenharmony_ci { 1377e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1378e5c31af7Sopenharmony_ci } 1379e5c31af7Sopenharmony_ci else 1380e5c31af7Sopenharmony_ci { 1381e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1382e5c31af7Sopenharmony_ci } 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci return STOP; 1385e5c31af7Sopenharmony_ci} 1386e5c31af7Sopenharmony_ci 1387e5c31af7Sopenharmony_ci/** Constructor 1388e5c31af7Sopenharmony_ci * 1389e5c31af7Sopenharmony_ci * @param context Test context 1390e5c31af7Sopenharmony_ci * @param extParams Not used. 1391e5c31af7Sopenharmony_ci * @param name Test case's name 1392e5c31af7Sopenharmony_ci * @param description Test case's description 1393e5c31af7Sopenharmony_ci **/ 1394e5c31af7Sopenharmony_ciGeometryShaderMaxImageUniformsTest::GeometryShaderMaxImageUniformsTest(Context& context, const ExtParameters& extParams, 1395e5c31af7Sopenharmony_ci const char* name, const char* description) 1396e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 1397e5c31af7Sopenharmony_ci , m_fs_id(0) 1398e5c31af7Sopenharmony_ci , m_gl_max_geometry_image_uniforms_ext_value(0) 1399e5c31af7Sopenharmony_ci , m_gs_id(0) 1400e5c31af7Sopenharmony_ci , m_po_id(0) 1401e5c31af7Sopenharmony_ci , m_texture_ids(NULL) 1402e5c31af7Sopenharmony_ci , m_tfbo_id(0) 1403e5c31af7Sopenharmony_ci , m_vao_id(0) 1404e5c31af7Sopenharmony_ci , m_vs_id(0) 1405e5c31af7Sopenharmony_ci{ 1406e5c31af7Sopenharmony_ci //Bug-15063 Only GLSL 4.50 supports opaque types 1407e5c31af7Sopenharmony_ci if (m_glslVersion >= glu::GLSL_VERSION_130) 1408e5c31af7Sopenharmony_ci { 1409e5c31af7Sopenharmony_ci m_glslVersion = glu::GLSL_VERSION_450; 1410e5c31af7Sopenharmony_ci } 1411e5c31af7Sopenharmony_ci} 1412e5c31af7Sopenharmony_ci 1413e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 1414e5c31af7Sopenharmony_civoid GeometryShaderMaxImageUniformsTest::deinit() 1415e5c31af7Sopenharmony_ci{ 1416e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1417e5c31af7Sopenharmony_ci 1418e5c31af7Sopenharmony_ci if (m_fs_id != 0) 1419e5c31af7Sopenharmony_ci { 1420e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 1421e5c31af7Sopenharmony_ci 1422e5c31af7Sopenharmony_ci m_fs_id = 0; 1423e5c31af7Sopenharmony_ci } 1424e5c31af7Sopenharmony_ci 1425e5c31af7Sopenharmony_ci if (m_gs_id != 0) 1426e5c31af7Sopenharmony_ci { 1427e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 1428e5c31af7Sopenharmony_ci 1429e5c31af7Sopenharmony_ci m_gs_id = 0; 1430e5c31af7Sopenharmony_ci } 1431e5c31af7Sopenharmony_ci 1432e5c31af7Sopenharmony_ci if (m_po_id != 0) 1433e5c31af7Sopenharmony_ci { 1434e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 1435e5c31af7Sopenharmony_ci 1436e5c31af7Sopenharmony_ci m_po_id = 0; 1437e5c31af7Sopenharmony_ci } 1438e5c31af7Sopenharmony_ci 1439e5c31af7Sopenharmony_ci if (m_texture_ids != NULL) 1440e5c31af7Sopenharmony_ci { 1441e5c31af7Sopenharmony_ci gl.deleteTextures(m_gl_max_geometry_image_uniforms_ext_value, m_texture_ids); 1442e5c31af7Sopenharmony_ci 1443e5c31af7Sopenharmony_ci delete[] m_texture_ids; 1444e5c31af7Sopenharmony_ci m_texture_ids = NULL; 1445e5c31af7Sopenharmony_ci } 1446e5c31af7Sopenharmony_ci 1447e5c31af7Sopenharmony_ci if (m_tfbo_id != 0) 1448e5c31af7Sopenharmony_ci { 1449e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_tfbo_id); 1450e5c31af7Sopenharmony_ci m_tfbo_id = 0; 1451e5c31af7Sopenharmony_ci } 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci if (m_vao_id != 0) 1454e5c31af7Sopenharmony_ci { 1455e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 1456e5c31af7Sopenharmony_ci m_vao_id = 0; 1457e5c31af7Sopenharmony_ci } 1458e5c31af7Sopenharmony_ci 1459e5c31af7Sopenharmony_ci if (m_vs_id != 0) 1460e5c31af7Sopenharmony_ci { 1461e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 1462e5c31af7Sopenharmony_ci 1463e5c31af7Sopenharmony_ci m_vs_id = 0; 1464e5c31af7Sopenharmony_ci } 1465e5c31af7Sopenharmony_ci 1466e5c31af7Sopenharmony_ci /* Set GL_PACK_ALIGNMENT to default value. */ 1467e5c31af7Sopenharmony_ci gl.pixelStorei(GL_PACK_ALIGNMENT, 4 /*default value taken from specification*/); 1468e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed for GL_PACK_ALIGNMENT pname."); 1469e5c31af7Sopenharmony_ci 1470e5c31af7Sopenharmony_ci /* Release base class */ 1471e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 1472e5c31af7Sopenharmony_ci} 1473e5c31af7Sopenharmony_ci 1474e5c31af7Sopenharmony_ci/* Retrieves test-specific geometry shader source code. 1475e5c31af7Sopenharmony_ci * 1476e5c31af7Sopenharmony_ci * @return Requested string. 1477e5c31af7Sopenharmony_ci */ 1478e5c31af7Sopenharmony_cistd::string GeometryShaderMaxImageUniformsTest::getGSCode() 1479e5c31af7Sopenharmony_ci{ 1480e5c31af7Sopenharmony_ci std::stringstream code_sstream; 1481e5c31af7Sopenharmony_ci 1482e5c31af7Sopenharmony_ci /* Form the GS */ 1483e5c31af7Sopenharmony_ci code_sstream << "${VERSION}\n" 1484e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 1485e5c31af7Sopenharmony_ci "\n" 1486e5c31af7Sopenharmony_ci "layout (points) in;\n" 1487e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 1488e5c31af7Sopenharmony_ci "\n" 1489e5c31af7Sopenharmony_ci "precision highp iimage2D;\n" 1490e5c31af7Sopenharmony_ci "\n" 1491e5c31af7Sopenharmony_ci "ivec4 counter = ivec4(0);\n" 1492e5c31af7Sopenharmony_ci "\n"; 1493e5c31af7Sopenharmony_ci 1494e5c31af7Sopenharmony_ci for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img) 1495e5c31af7Sopenharmony_ci { 1496e5c31af7Sopenharmony_ci code_sstream << "layout(binding = " << n_img << ", r32i) uniform iimage2D img" << n_img << ";\n"; 1497e5c31af7Sopenharmony_ci } 1498e5c31af7Sopenharmony_ci 1499e5c31af7Sopenharmony_ci code_sstream << "\n" 1500e5c31af7Sopenharmony_ci "void main()\n" 1501e5c31af7Sopenharmony_ci "{\n"; 1502e5c31af7Sopenharmony_ci 1503e5c31af7Sopenharmony_ci for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img) 1504e5c31af7Sopenharmony_ci { 1505e5c31af7Sopenharmony_ci code_sstream << " counter += imageLoad(img" << n_img << ", ivec2(0, 0));\n"; 1506e5c31af7Sopenharmony_ci } 1507e5c31af7Sopenharmony_ci 1508e5c31af7Sopenharmony_ci code_sstream << "\n" 1509e5c31af7Sopenharmony_ci " gl_Position = vec4(float(counter.x), 0.0, 0.0, 1.0);\n" 1510e5c31af7Sopenharmony_ci " EmitVertex();\n" 1511e5c31af7Sopenharmony_ci "}\n"; 1512e5c31af7Sopenharmony_ci 1513e5c31af7Sopenharmony_ci /* Form a specialized version of the GS source code */ 1514e5c31af7Sopenharmony_ci std::string gs_code = code_sstream.str(); 1515e5c31af7Sopenharmony_ci const char* gs_code_raw = gs_code.c_str(); 1516e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1 /* parts */, &gs_code_raw); 1517e5c31af7Sopenharmony_ci 1518e5c31af7Sopenharmony_ci return gs_code_specialized; 1519e5c31af7Sopenharmony_ci} 1520e5c31af7Sopenharmony_ci 1521e5c31af7Sopenharmony_ci/** Executes the test. 1522e5c31af7Sopenharmony_ci * 1523e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1524e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 1525e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 1526e5c31af7Sopenharmony_ci **/ 1527e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderMaxImageUniformsTest::iterate() 1528e5c31af7Sopenharmony_ci{ 1529e5c31af7Sopenharmony_ci glw::GLint counter = 0; 1530e5c31af7Sopenharmony_ci glw::GLint expectedValue = 0; 1531e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 1532e5c31af7Sopenharmony_ci glw::GLfloat* ptr = DE_NULL; 1533e5c31af7Sopenharmony_ci bool result = true; 1534e5c31af7Sopenharmony_ci const glw::GLchar* feedbackVaryings[] = { "gl_Position" }; 1535e5c31af7Sopenharmony_ci 1536e5c31af7Sopenharmony_ci std::string fs_code_specialized = ""; 1537e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = DE_NULL; 1538e5c31af7Sopenharmony_ci std::string gs_code_specialized = ""; 1539e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = DE_NULL; 1540e5c31af7Sopenharmony_ci std::string vs_code_specialized = ""; 1541e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = DE_NULL; 1542e5c31af7Sopenharmony_ci 1543e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 1544e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 1545e5c31af7Sopenharmony_ci { 1546e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1547e5c31af7Sopenharmony_ci } 1548e5c31af7Sopenharmony_ci 1549e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1550e5c31af7Sopenharmony_ci 1551e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname value */ 1552e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &m_gl_max_geometry_image_uniforms_ext_value); 1553e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname"); 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT pname value */ 1556e5c31af7Sopenharmony_ci glw::GLint m_gl_max_geometry_texture_image_units_ext_value = 0; 1557e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_gl_max_geometry_texture_image_units_ext_value); 1558e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname"); 1559e5c31af7Sopenharmony_ci 1560e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_IMAGE_UNITS pname value */ 1561e5c31af7Sopenharmony_ci glw::GLint m_gl_max_image_units_value = 0; 1562e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_IMAGE_UNITS, &m_gl_max_image_units_value); 1563e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_IMAGE_UNITS pname"); 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci /* Check if m_gl_max_geometry_image_uniforms_value is less than or equal zero. */ 1566e5c31af7Sopenharmony_ci if (m_gl_max_geometry_image_uniforms_ext_value <= 0) 1567e5c31af7Sopenharmony_ci { 1568e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value " 1569e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_image_uniforms_ext_value 1570e5c31af7Sopenharmony_ci << "]" 1571e5c31af7Sopenharmony_ci " is less than or equal zero. Image uniforms in Geometry Shader" 1572e5c31af7Sopenharmony_ci " are not supported." 1573e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1574e5c31af7Sopenharmony_ci 1575e5c31af7Sopenharmony_ci if (m_gl_max_geometry_image_uniforms_ext_value == 0) 1576e5c31af7Sopenharmony_ci { 1577e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT is 0"); 1578e5c31af7Sopenharmony_ci } 1579e5c31af7Sopenharmony_ci else 1580e5c31af7Sopenharmony_ci { 1581e5c31af7Sopenharmony_ci result = false; 1582e5c31af7Sopenharmony_ci goto end; 1583e5c31af7Sopenharmony_ci } 1584e5c31af7Sopenharmony_ci } 1585e5c31af7Sopenharmony_ci 1586e5c31af7Sopenharmony_ci /* Check if m_gl_max_image_units_value is less than m_gl_max_geometry_image_uniforms_value. */ 1587e5c31af7Sopenharmony_ci if (m_gl_max_image_units_value < m_gl_max_geometry_image_uniforms_ext_value) 1588e5c31af7Sopenharmony_ci { 1589e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value " 1590e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_image_uniforms_ext_value 1591e5c31af7Sopenharmony_ci << "]" 1592e5c31af7Sopenharmony_ci " is greater than GL_MAX_IMAGE_UNITS query value " 1593e5c31af7Sopenharmony_ci "[" 1594e5c31af7Sopenharmony_ci << m_gl_max_image_units_value << "]." << tcu::TestLog::EndMessage; 1595e5c31af7Sopenharmony_ci 1596e5c31af7Sopenharmony_ci result = false; 1597e5c31af7Sopenharmony_ci goto end; 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci /* Create a program object. */ 1601e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 1602e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_ci /* Create shader objects. */ 1605e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 1606e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 1607e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 1608e5c31af7Sopenharmony_ci 1609e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 1610e5c31af7Sopenharmony_ci 1611e5c31af7Sopenharmony_ci /* Configure which outputs should be captured by Transform Feedback. */ 1612e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS); 1613e5c31af7Sopenharmony_ci 1614e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 1615e5c31af7Sopenharmony_ci 1616e5c31af7Sopenharmony_ci /* Try to link the test program object */ 1617e5c31af7Sopenharmony_ci fs_code_specialized = specializeShader(1, &minimal_fs_code); 1618e5c31af7Sopenharmony_ci fs_code_specialized_raw = fs_code_specialized.c_str(); 1619e5c31af7Sopenharmony_ci 1620e5c31af7Sopenharmony_ci gs_code_specialized = getGSCode(); 1621e5c31af7Sopenharmony_ci gs_code_specialized_raw = gs_code_specialized.c_str(); 1622e5c31af7Sopenharmony_ci 1623e5c31af7Sopenharmony_ci vs_code_specialized = specializeShader(1, &minimal_vs_code); 1624e5c31af7Sopenharmony_ci vs_code_specialized_raw = vs_code_specialized.c_str(); 1625e5c31af7Sopenharmony_ci 1626e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 1627e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */ 1628e5c31af7Sopenharmony_ci &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */ 1629e5c31af7Sopenharmony_ci &fs_code_specialized_raw, &has_shader_compilation_failed)) 1630e5c31af7Sopenharmony_ci { 1631e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage; 1632e5c31af7Sopenharmony_ci 1633e5c31af7Sopenharmony_ci result = false; 1634e5c31af7Sopenharmony_ci goto end; 1635e5c31af7Sopenharmony_ci } 1636e5c31af7Sopenharmony_ci 1637e5c31af7Sopenharmony_ci /* Use program. */ 1638e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 1639e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 1640e5c31af7Sopenharmony_ci 1641e5c31af7Sopenharmony_ci /* Allocate memory for m_max_image_units_value Texture Objects. */ 1642e5c31af7Sopenharmony_ci m_texture_ids = new glw::GLuint[m_gl_max_geometry_image_uniforms_ext_value]; 1643e5c31af7Sopenharmony_ci 1644e5c31af7Sopenharmony_ci /* Generate m_max_image_units_value Texture Objects. */ 1645e5c31af7Sopenharmony_ci gl.genTextures(m_gl_max_geometry_image_uniforms_ext_value, m_texture_ids); 1646e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 1647e5c31af7Sopenharmony_ci 1648e5c31af7Sopenharmony_ci /* Set GL_PACK_ALIGNMENT to 1. */ 1649e5c31af7Sopenharmony_ci gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 1650e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed for GL_PACK_ALIGNMENT pname."); 1651e5c31af7Sopenharmony_ci 1652e5c31af7Sopenharmony_ci /* Bind integer 2D texture objects of resolution 1x1 to image units. */ 1653e5c31af7Sopenharmony_ci for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img) 1654e5c31af7Sopenharmony_ci { 1655e5c31af7Sopenharmony_ci glw::GLint texture = m_texture_ids[n_img]; 1656e5c31af7Sopenharmony_ci glw::GLint value = n_img + 1; 1657e5c31af7Sopenharmony_ci 1658e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, texture); 1659e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 1660e5c31af7Sopenharmony_ci 1661e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_R32I, 1 /*width*/, 1 /*height*/); 1662e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 1663e5c31af7Sopenharmony_ci 1664e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_2D, 0 /*level*/, 0 /*xoffset*/, 0 /*yoffset*/, 1 /*width*/, 1 /*height*/, 1665e5c31af7Sopenharmony_ci GL_RED_INTEGER, GL_INT, &value); 1666e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed."); 1667e5c31af7Sopenharmony_ci 1668e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1669e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed."); 1670e5c31af7Sopenharmony_ci 1671e5c31af7Sopenharmony_ci gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1672e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed."); 1673e5c31af7Sopenharmony_ci 1674e5c31af7Sopenharmony_ci gl.bindImageTexture(n_img, texture, 0 /*level*/, GL_FALSE /*is layered?*/, 0 /*layer*/, GL_READ_ONLY, GL_R32I); 1675e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed."); 1676e5c31af7Sopenharmony_ci } 1677e5c31af7Sopenharmony_ci 1678e5c31af7Sopenharmony_ci /* Configure VAO. */ 1679e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 1680e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 1681e5c31af7Sopenharmony_ci 1682e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 1683e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 1684e5c31af7Sopenharmony_ci 1685e5c31af7Sopenharmony_ci /* Create a Buffer Object for Transform Feedback's outputs. */ 1686e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_tfbo_id); 1687e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 1688e5c31af7Sopenharmony_ci 1689e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id); 1690e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 1691e5c31af7Sopenharmony_ci 1692e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, NULL, GL_STATIC_READ); 1693e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_ci /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */ 1696e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tfbo_id); 1697e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 1698e5c31af7Sopenharmony_ci 1699e5c31af7Sopenharmony_ci /* Disable rasterization and make a draw call. After that, turn on rasterization. */ 1700e5c31af7Sopenharmony_ci gl.enable(GL_RASTERIZER_DISCARD); 1701e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname."); 1702e5c31af7Sopenharmony_ci 1703e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 1704e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 1705e5c31af7Sopenharmony_ci 1706e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/); 1707e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname."); 1708e5c31af7Sopenharmony_ci 1709e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 1710e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 1711e5c31af7Sopenharmony_ci 1712e5c31af7Sopenharmony_ci gl.disable(GL_RASTERIZER_DISCARD); 1713e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname."); 1714e5c31af7Sopenharmony_ci 1715e5c31af7Sopenharmony_ci /* Retrieve value from Transform Feedback. */ 1716e5c31af7Sopenharmony_ci counter = 0; 1717e5c31af7Sopenharmony_ci ptr = (glw::GLfloat*)gl.mapBufferRange( 1718e5c31af7Sopenharmony_ci GL_ARRAY_BUFFER, 0, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT); 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 1721e5c31af7Sopenharmony_ci 1722e5c31af7Sopenharmony_ci counter = int(ptr[0] + 0.5f); 1723e5c31af7Sopenharmony_ci 1724e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_ARRAY_BUFFER); 1725e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 1726e5c31af7Sopenharmony_ci 1727e5c31af7Sopenharmony_ci /* Calculate expected value. */ 1728e5c31af7Sopenharmony_ci expectedValue = m_gl_max_geometry_image_uniforms_ext_value * (m_gl_max_geometry_image_uniforms_ext_value + 1) / 2; 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ci if (counter != expectedValue) 1731e5c31af7Sopenharmony_ci { 1732e5c31af7Sopenharmony_ci result = false; 1733e5c31af7Sopenharmony_ci } 1734e5c31af7Sopenharmony_ci 1735e5c31af7Sopenharmony_ciend: 1736e5c31af7Sopenharmony_ci if (result) 1737e5c31af7Sopenharmony_ci { 1738e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1739e5c31af7Sopenharmony_ci } 1740e5c31af7Sopenharmony_ci else 1741e5c31af7Sopenharmony_ci { 1742e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1743e5c31af7Sopenharmony_ci } 1744e5c31af7Sopenharmony_ci 1745e5c31af7Sopenharmony_ci return STOP; 1746e5c31af7Sopenharmony_ci} 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci/** Constructor 1749e5c31af7Sopenharmony_ci * 1750e5c31af7Sopenharmony_ci * @param context Test context 1751e5c31af7Sopenharmony_ci * @param extParams Not used. 1752e5c31af7Sopenharmony_ci * @param name Test case's name 1753e5c31af7Sopenharmony_ci * @param description Test case's description 1754e5c31af7Sopenharmony_ci **/ 1755e5c31af7Sopenharmony_ciGeometryShaderMaxShaderStorageBlocksTest::GeometryShaderMaxShaderStorageBlocksTest(Context& context, 1756e5c31af7Sopenharmony_ci const ExtParameters& extParams, 1757e5c31af7Sopenharmony_ci const char* name, 1758e5c31af7Sopenharmony_ci const char* description) 1759e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 1760e5c31af7Sopenharmony_ci , m_fs_id(0) 1761e5c31af7Sopenharmony_ci , m_gl_max_geometry_shader_storage_blocks_ext_value(0) 1762e5c31af7Sopenharmony_ci , m_gs_id(0) 1763e5c31af7Sopenharmony_ci , m_po_id(0) 1764e5c31af7Sopenharmony_ci , m_ssbo_id(0) 1765e5c31af7Sopenharmony_ci , m_tfbo_id(0) 1766e5c31af7Sopenharmony_ci , m_vao_id(0) 1767e5c31af7Sopenharmony_ci , m_vs_id(0) 1768e5c31af7Sopenharmony_ci{ 1769e5c31af7Sopenharmony_ci} 1770e5c31af7Sopenharmony_ci 1771e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 1772e5c31af7Sopenharmony_civoid GeometryShaderMaxShaderStorageBlocksTest::deinit() 1773e5c31af7Sopenharmony_ci{ 1774e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1775e5c31af7Sopenharmony_ci 1776e5c31af7Sopenharmony_ci if (m_fs_id != 0) 1777e5c31af7Sopenharmony_ci { 1778e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 1779e5c31af7Sopenharmony_ci m_fs_id = 0; 1780e5c31af7Sopenharmony_ci } 1781e5c31af7Sopenharmony_ci 1782e5c31af7Sopenharmony_ci if (m_gs_id != 0) 1783e5c31af7Sopenharmony_ci { 1784e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 1785e5c31af7Sopenharmony_ci m_gs_id = 0; 1786e5c31af7Sopenharmony_ci } 1787e5c31af7Sopenharmony_ci 1788e5c31af7Sopenharmony_ci if (m_po_id != 0) 1789e5c31af7Sopenharmony_ci { 1790e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 1791e5c31af7Sopenharmony_ci m_po_id = 0; 1792e5c31af7Sopenharmony_ci } 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci if (m_ssbo_id != 0) 1795e5c31af7Sopenharmony_ci { 1796e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_ssbo_id); 1797e5c31af7Sopenharmony_ci m_ssbo_id = 0; 1798e5c31af7Sopenharmony_ci } 1799e5c31af7Sopenharmony_ci 1800e5c31af7Sopenharmony_ci if (m_tfbo_id != 0) 1801e5c31af7Sopenharmony_ci { 1802e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_tfbo_id); 1803e5c31af7Sopenharmony_ci m_tfbo_id = 0; 1804e5c31af7Sopenharmony_ci } 1805e5c31af7Sopenharmony_ci 1806e5c31af7Sopenharmony_ci if (m_vao_id != 0) 1807e5c31af7Sopenharmony_ci { 1808e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 1809e5c31af7Sopenharmony_ci m_vao_id = 0; 1810e5c31af7Sopenharmony_ci } 1811e5c31af7Sopenharmony_ci 1812e5c31af7Sopenharmony_ci if (m_vs_id != 0) 1813e5c31af7Sopenharmony_ci { 1814e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 1815e5c31af7Sopenharmony_ci m_vs_id = 0; 1816e5c31af7Sopenharmony_ci } 1817e5c31af7Sopenharmony_ci 1818e5c31af7Sopenharmony_ci /* Release base class */ 1819e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 1820e5c31af7Sopenharmony_ci} 1821e5c31af7Sopenharmony_ci 1822e5c31af7Sopenharmony_ci/* Retrieves test-specific geometry shader source code. 1823e5c31af7Sopenharmony_ci * 1824e5c31af7Sopenharmony_ci * @return Requested string. 1825e5c31af7Sopenharmony_ci */ 1826e5c31af7Sopenharmony_cistd::string GeometryShaderMaxShaderStorageBlocksTest::getGSCode() 1827e5c31af7Sopenharmony_ci{ 1828e5c31af7Sopenharmony_ci std::stringstream code_sstream; 1829e5c31af7Sopenharmony_ci 1830e5c31af7Sopenharmony_ci /* Form the GS */ 1831e5c31af7Sopenharmony_ci code_sstream << "${VERSION}\n" 1832e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 1833e5c31af7Sopenharmony_ci "\n" 1834e5c31af7Sopenharmony_ci "layout (points) in;\n" 1835e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 1836e5c31af7Sopenharmony_ci "\n" 1837e5c31af7Sopenharmony_ci "int counter = 0;\n" 1838e5c31af7Sopenharmony_ci "\n"; 1839e5c31af7Sopenharmony_ci 1840e5c31af7Sopenharmony_ci for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb) 1841e5c31af7Sopenharmony_ci { 1842e5c31af7Sopenharmony_ci code_sstream << "layout(binding = " << n_ssb << ") buffer ssb" << n_ssb << " \n{\n" 1843e5c31af7Sopenharmony_ci << " int value;\n" 1844e5c31af7Sopenharmony_ci << "} S_SSB" << n_ssb << ";\n\n"; 1845e5c31af7Sopenharmony_ci } 1846e5c31af7Sopenharmony_ci 1847e5c31af7Sopenharmony_ci code_sstream << "\n" 1848e5c31af7Sopenharmony_ci "void main()\n" 1849e5c31af7Sopenharmony_ci "{\n"; 1850e5c31af7Sopenharmony_ci 1851e5c31af7Sopenharmony_ci for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb) 1852e5c31af7Sopenharmony_ci { 1853e5c31af7Sopenharmony_ci code_sstream << " counter += S_SSB" << n_ssb << ".value++;\n"; 1854e5c31af7Sopenharmony_ci } 1855e5c31af7Sopenharmony_ci 1856e5c31af7Sopenharmony_ci code_sstream << "\n" 1857e5c31af7Sopenharmony_ci " gl_Position = vec4(float(counter), 0.0, 0.0, 1.0);\n" 1858e5c31af7Sopenharmony_ci " EmitVertex();\n" 1859e5c31af7Sopenharmony_ci "}\n"; 1860e5c31af7Sopenharmony_ci 1861e5c31af7Sopenharmony_ci /* Form a specialized version of the GS source code */ 1862e5c31af7Sopenharmony_ci std::string gs_code = code_sstream.str(); 1863e5c31af7Sopenharmony_ci const char* gs_code_raw = gs_code.c_str(); 1864e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1 /* parts */, &gs_code_raw); 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci return gs_code_specialized; 1867e5c31af7Sopenharmony_ci} 1868e5c31af7Sopenharmony_ci 1869e5c31af7Sopenharmony_ci/** Executes the test. 1870e5c31af7Sopenharmony_ci * 1871e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 1872e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 1873e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 1874e5c31af7Sopenharmony_ci **/ 1875e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderMaxShaderStorageBlocksTest::iterate() 1876e5c31af7Sopenharmony_ci{ 1877e5c31af7Sopenharmony_ci glw::GLint counter = 0; 1878e5c31af7Sopenharmony_ci glw::GLint expectedValue = 0; 1879e5c31af7Sopenharmony_ci const glw::GLchar* feedbackVaryings[] = { "gl_Position" }; 1880e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 1881e5c31af7Sopenharmony_ci const glw::GLfloat initial_buffer_data[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 1882e5c31af7Sopenharmony_ci glw::GLint int_alignment = 0; 1883e5c31af7Sopenharmony_ci const glw::GLint int_size = sizeof(glw::GLint); 1884e5c31af7Sopenharmony_ci glw::GLint* ptrSSBO_data = DE_NULL; 1885e5c31af7Sopenharmony_ci glw::GLfloat* ptrTF_data = DE_NULL; 1886e5c31af7Sopenharmony_ci bool result = true; 1887e5c31af7Sopenharmony_ci glw::GLint ssbo_alignment = 0; 1888e5c31af7Sopenharmony_ci glw::GLint* ssbo_data = DE_NULL; 1889e5c31af7Sopenharmony_ci glw::GLint ssbo_data_size = 0; 1890e5c31af7Sopenharmony_ci 1891e5c31af7Sopenharmony_ci std::string fs_code_specialized = ""; 1892e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = DE_NULL; 1893e5c31af7Sopenharmony_ci std::string gs_code_specialized = ""; 1894e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = DE_NULL; 1895e5c31af7Sopenharmony_ci std::string vs_code_specialized = ""; 1896e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = DE_NULL; 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 1899e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 1900e5c31af7Sopenharmony_ci { 1901e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 1902e5c31af7Sopenharmony_ci } 1903e5c31af7Sopenharmony_ci 1904e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1905e5c31af7Sopenharmony_ci 1906e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname value */ 1907e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, 1908e5c31af7Sopenharmony_ci &m_gl_max_geometry_shader_storage_blocks_ext_value); 1909e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname"); 1910e5c31af7Sopenharmony_ci 1911e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname value */ 1912e5c31af7Sopenharmony_ci glw::GLint m_gl_max_shader_storage_buffer_bindings_value = 0; 1913e5c31af7Sopenharmony_ci 1914e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &m_gl_max_shader_storage_buffer_bindings_value); 1915e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname"); 1916e5c31af7Sopenharmony_ci 1917e5c31af7Sopenharmony_ci /* Check if m_gl_max_shader_storage_blocks_value is less than or equal zero. */ 1918e5c31af7Sopenharmony_ci if (m_gl_max_geometry_shader_storage_blocks_ext_value <= 0) 1919e5c31af7Sopenharmony_ci { 1920e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value " 1921e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value 1922e5c31af7Sopenharmony_ci << "]" 1923e5c31af7Sopenharmony_ci " is less than or equal zero. Shader Storage Blocks" 1924e5c31af7Sopenharmony_ci " in Geometry Shader are not supported." 1925e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci if (m_gl_max_geometry_shader_storage_blocks_ext_value == 0) 1928e5c31af7Sopenharmony_ci { 1929e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT is 0"); 1930e5c31af7Sopenharmony_ci } 1931e5c31af7Sopenharmony_ci else 1932e5c31af7Sopenharmony_ci { 1933e5c31af7Sopenharmony_ci result = false; 1934e5c31af7Sopenharmony_ci goto end; 1935e5c31af7Sopenharmony_ci } 1936e5c31af7Sopenharmony_ci } 1937e5c31af7Sopenharmony_ci 1938e5c31af7Sopenharmony_ci /* Check if m_gl_max_shader_storage_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */ 1939e5c31af7Sopenharmony_ci if (m_gl_max_shader_storage_buffer_bindings_value < m_gl_max_geometry_shader_storage_blocks_ext_value) 1940e5c31af7Sopenharmony_ci { 1941e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value " 1942e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value 1943e5c31af7Sopenharmony_ci << "]" 1944e5c31af7Sopenharmony_ci " is greater than GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS query value " 1945e5c31af7Sopenharmony_ci "[" 1946e5c31af7Sopenharmony_ci << m_gl_max_shader_storage_buffer_bindings_value << "]." << tcu::TestLog::EndMessage; 1947e5c31af7Sopenharmony_ci 1948e5c31af7Sopenharmony_ci result = false; 1949e5c31af7Sopenharmony_ci goto end; 1950e5c31af7Sopenharmony_ci } 1951e5c31af7Sopenharmony_ci 1952e5c31af7Sopenharmony_ci /* Create a program object. */ 1953e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 1954e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 1955e5c31af7Sopenharmony_ci 1956e5c31af7Sopenharmony_ci /* Create shader objects. */ 1957e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 1958e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 1959e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 1962e5c31af7Sopenharmony_ci 1963e5c31af7Sopenharmony_ci /* Configure which outputs should be captured by Transform Feedback. */ 1964e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS); 1965e5c31af7Sopenharmony_ci 1966e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed."); 1967e5c31af7Sopenharmony_ci 1968e5c31af7Sopenharmony_ci /* Try to link the test program object */ 1969e5c31af7Sopenharmony_ci fs_code_specialized = specializeShader(1, &minimal_fs_code); 1970e5c31af7Sopenharmony_ci fs_code_specialized_raw = fs_code_specialized.c_str(); 1971e5c31af7Sopenharmony_ci 1972e5c31af7Sopenharmony_ci gs_code_specialized = getGSCode(); 1973e5c31af7Sopenharmony_ci gs_code_specialized_raw = gs_code_specialized.c_str(); 1974e5c31af7Sopenharmony_ci 1975e5c31af7Sopenharmony_ci vs_code_specialized = specializeShader(1, &minimal_vs_code); 1976e5c31af7Sopenharmony_ci vs_code_specialized_raw = vs_code_specialized.c_str(); 1977e5c31af7Sopenharmony_ci 1978e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 1979e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */ 1980e5c31af7Sopenharmony_ci &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */ 1981e5c31af7Sopenharmony_ci &fs_code_specialized_raw, &has_shader_compilation_failed)) 1982e5c31af7Sopenharmony_ci { 1983e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage; 1984e5c31af7Sopenharmony_ci 1985e5c31af7Sopenharmony_ci result = false; 1986e5c31af7Sopenharmony_ci goto end; 1987e5c31af7Sopenharmony_ci } 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci /* Prepare data for Shader Storage Buffer Object. */ 1990e5c31af7Sopenharmony_ci gl.getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment); 1991e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed."); 1992e5c31af7Sopenharmony_ci 1993e5c31af7Sopenharmony_ci int_alignment = ssbo_alignment / int_size; 1994e5c31af7Sopenharmony_ci ssbo_data_size = m_gl_max_geometry_shader_storage_blocks_ext_value * ssbo_alignment; 1995e5c31af7Sopenharmony_ci ssbo_data = new glw::GLint[ssbo_data_size]; 1996e5c31af7Sopenharmony_ci 1997e5c31af7Sopenharmony_ci if ((ssbo_alignment % int_size) != 0) 1998e5c31af7Sopenharmony_ci { 1999e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT query value " 2000e5c31af7Sopenharmony_ci "[" 2001e5c31af7Sopenharmony_ci << ssbo_alignment << "]" 2002e5c31af7Sopenharmony_ci "divide with remainder by the size of GLint " 2003e5c31af7Sopenharmony_ci "[" 2004e5c31af7Sopenharmony_ci << int_size << "]" << tcu::TestLog::EndMessage; 2005e5c31af7Sopenharmony_ci 2006e5c31af7Sopenharmony_ci result = false; 2007e5c31af7Sopenharmony_ci goto end; 2008e5c31af7Sopenharmony_ci } 2009e5c31af7Sopenharmony_ci 2010e5c31af7Sopenharmony_ci for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i) 2011e5c31af7Sopenharmony_ci { 2012e5c31af7Sopenharmony_ci ssbo_data[i * int_alignment] = i + 1; 2013e5c31af7Sopenharmony_ci } 2014e5c31af7Sopenharmony_ci 2015e5c31af7Sopenharmony_ci /* Create Shader Storage Buffer Object. */ 2016e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_ssbo_id); 2017e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 2018e5c31af7Sopenharmony_ci 2019e5c31af7Sopenharmony_ci gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo_id); 2020e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname."); 2021e5c31af7Sopenharmony_ci 2022e5c31af7Sopenharmony_ci gl.bufferData(GL_SHADER_STORAGE_BUFFER, ssbo_data_size, ssbo_data, GL_DYNAMIC_COPY); 2023e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 2024e5c31af7Sopenharmony_ci 2025e5c31af7Sopenharmony_ci /* Free unused memory. */ 2026e5c31af7Sopenharmony_ci delete[] ssbo_data; 2027e5c31af7Sopenharmony_ci ssbo_data = NULL; 2028e5c31af7Sopenharmony_ci 2029e5c31af7Sopenharmony_ci /* Bind specific m_ssbo_id buffer region to a specific Shader Storage Buffer binding point. */ 2030e5c31af7Sopenharmony_ci for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb) 2031e5c31af7Sopenharmony_ci { 2032e5c31af7Sopenharmony_ci glw::GLuint offset = n_ssb * ssbo_alignment; 2033e5c31af7Sopenharmony_ci 2034e5c31af7Sopenharmony_ci gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, n_ssb /*binding index*/, m_ssbo_id, offset, int_size); 2035e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed."); 2036e5c31af7Sopenharmony_ci } 2037e5c31af7Sopenharmony_ci 2038e5c31af7Sopenharmony_ci /* Configure VAO. */ 2039e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 2040e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 2041e5c31af7Sopenharmony_ci 2042e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 2043e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci /* Create a Buffer Object for Transform Feedback's outputs. */ 2046e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_tfbo_id); 2047e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 2048e5c31af7Sopenharmony_ci 2049e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id); 2050e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 2051e5c31af7Sopenharmony_ci 2052e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, initial_buffer_data, 2053e5c31af7Sopenharmony_ci GL_STATIC_READ); 2054e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 2055e5c31af7Sopenharmony_ci 2056e5c31af7Sopenharmony_ci /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */ 2057e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id); 2058e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed."); 2059e5c31af7Sopenharmony_ci 2060e5c31af7Sopenharmony_ci /* Use program. */ 2061e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 2062e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 2063e5c31af7Sopenharmony_ci 2064e5c31af7Sopenharmony_ci /* Disable rasterization and make a draw call. After that, turn on rasterization. */ 2065e5c31af7Sopenharmony_ci gl.enable(GL_RASTERIZER_DISCARD); 2066e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname."); 2067e5c31af7Sopenharmony_ci 2068e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 2069e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed."); 2070e5c31af7Sopenharmony_ci 2071e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/); 2072e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname."); 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 2075e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed."); 2076e5c31af7Sopenharmony_ci 2077e5c31af7Sopenharmony_ci gl.disable(GL_RASTERIZER_DISCARD); 2078e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname."); 2079e5c31af7Sopenharmony_ci 2080e5c31af7Sopenharmony_ci /* Retrieve value from Transform Feedback. */ 2081e5c31af7Sopenharmony_ci ptrTF_data = (glw::GLfloat*)gl.mapBufferRange( 2082e5c31af7Sopenharmony_ci GL_ARRAY_BUFFER, 0 /*offset*/, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT); 2083e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci counter = int(ptrTF_data[0] + 0.5f); 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_ARRAY_BUFFER); 2088e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 2089e5c31af7Sopenharmony_ci 2090e5c31af7Sopenharmony_ci ptrTF_data = NULL; 2091e5c31af7Sopenharmony_ci 2092e5c31af7Sopenharmony_ci /* Retrieve values from Shader Storage Buffer Object. */ 2093e5c31af7Sopenharmony_ci ptrSSBO_data = 2094e5c31af7Sopenharmony_ci (glw::GLint*)gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0 /*offset*/, ssbo_data_size, GL_MAP_READ_BIT); 2095e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 2096e5c31af7Sopenharmony_ci 2097e5c31af7Sopenharmony_ci for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i) 2098e5c31af7Sopenharmony_ci { 2099e5c31af7Sopenharmony_ci if (ptrSSBO_data[i * int_alignment] != i + 2) 2100e5c31af7Sopenharmony_ci { 2101e5c31af7Sopenharmony_ci result = false; 2102e5c31af7Sopenharmony_ci 2103e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Value read from Shader Storage Buffer " 2104e5c31af7Sopenharmony_ci "[" 2105e5c31af7Sopenharmony_ci << ptrSSBO_data[i * int_alignment] << "] " 2106e5c31af7Sopenharmony_ci "at index " 2107e5c31af7Sopenharmony_ci "[" 2108e5c31af7Sopenharmony_ci << i * int_alignment << "]" 2109e5c31af7Sopenharmony_ci "is not equal to expected value " 2110e5c31af7Sopenharmony_ci "[" 2111e5c31af7Sopenharmony_ci << i + 2 << "]" << tcu::TestLog::EndMessage; 2112e5c31af7Sopenharmony_ci 2113e5c31af7Sopenharmony_ci break; 2114e5c31af7Sopenharmony_ci } 2115e5c31af7Sopenharmony_ci } 2116e5c31af7Sopenharmony_ci 2117e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 2118e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 2119e5c31af7Sopenharmony_ci 2120e5c31af7Sopenharmony_ci ptrSSBO_data = NULL; 2121e5c31af7Sopenharmony_ci 2122e5c31af7Sopenharmony_ci /* Calculate expected value. */ 2123e5c31af7Sopenharmony_ci expectedValue = 2124e5c31af7Sopenharmony_ci m_gl_max_geometry_shader_storage_blocks_ext_value * (m_gl_max_geometry_shader_storage_blocks_ext_value + 1) / 2; 2125e5c31af7Sopenharmony_ci 2126e5c31af7Sopenharmony_ci if (counter != expectedValue) 2127e5c31af7Sopenharmony_ci { 2128e5c31af7Sopenharmony_ci result = false; 2129e5c31af7Sopenharmony_ci } 2130e5c31af7Sopenharmony_ci 2131e5c31af7Sopenharmony_ciend: 2132e5c31af7Sopenharmony_ci if (result) 2133e5c31af7Sopenharmony_ci { 2134e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2135e5c31af7Sopenharmony_ci } 2136e5c31af7Sopenharmony_ci else 2137e5c31af7Sopenharmony_ci { 2138e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2139e5c31af7Sopenharmony_ci } 2140e5c31af7Sopenharmony_ci 2141e5c31af7Sopenharmony_ci return STOP; 2142e5c31af7Sopenharmony_ci} 2143e5c31af7Sopenharmony_ci 2144e5c31af7Sopenharmony_ci/** Constructor 2145e5c31af7Sopenharmony_ci * 2146e5c31af7Sopenharmony_ci * @param context Test context 2147e5c31af7Sopenharmony_ci * @param extParams Not used. 2148e5c31af7Sopenharmony_ci * @param name Test case's name 2149e5c31af7Sopenharmony_ci * @param description Test case's description 2150e5c31af7Sopenharmony_ci **/ 2151e5c31af7Sopenharmony_ciGeometryShaderMaxAtomicCountersTest::GeometryShaderMaxAtomicCountersTest(Context& context, 2152e5c31af7Sopenharmony_ci const ExtParameters& extParams, 2153e5c31af7Sopenharmony_ci const char* name, const char* description) 2154e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 2155e5c31af7Sopenharmony_ci , m_acbo_id(0) 2156e5c31af7Sopenharmony_ci , m_fs_id(0) 2157e5c31af7Sopenharmony_ci , m_gl_max_geometry_atomic_counters_ext_value(0) 2158e5c31af7Sopenharmony_ci , m_gs_id(0) 2159e5c31af7Sopenharmony_ci , m_po_id(0) 2160e5c31af7Sopenharmony_ci , m_vao_id(0) 2161e5c31af7Sopenharmony_ci , m_vs_id(0) 2162e5c31af7Sopenharmony_ci{ 2163e5c31af7Sopenharmony_ci} 2164e5c31af7Sopenharmony_ci 2165e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 2166e5c31af7Sopenharmony_civoid GeometryShaderMaxAtomicCountersTest::deinit() 2167e5c31af7Sopenharmony_ci{ 2168e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2169e5c31af7Sopenharmony_ci 2170e5c31af7Sopenharmony_ci if (m_acbo_id != 0) 2171e5c31af7Sopenharmony_ci { 2172e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_acbo_id); 2173e5c31af7Sopenharmony_ci m_acbo_id = 0; 2174e5c31af7Sopenharmony_ci } 2175e5c31af7Sopenharmony_ci 2176e5c31af7Sopenharmony_ci if (m_fs_id != 0) 2177e5c31af7Sopenharmony_ci { 2178e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 2179e5c31af7Sopenharmony_ci m_fs_id = 0; 2180e5c31af7Sopenharmony_ci } 2181e5c31af7Sopenharmony_ci 2182e5c31af7Sopenharmony_ci if (m_gs_id != 0) 2183e5c31af7Sopenharmony_ci { 2184e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 2185e5c31af7Sopenharmony_ci m_gs_id = 0; 2186e5c31af7Sopenharmony_ci } 2187e5c31af7Sopenharmony_ci 2188e5c31af7Sopenharmony_ci if (m_po_id != 0) 2189e5c31af7Sopenharmony_ci { 2190e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 2191e5c31af7Sopenharmony_ci m_po_id = 0; 2192e5c31af7Sopenharmony_ci } 2193e5c31af7Sopenharmony_ci 2194e5c31af7Sopenharmony_ci if (m_vao_id != 0) 2195e5c31af7Sopenharmony_ci { 2196e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 2197e5c31af7Sopenharmony_ci m_vao_id = 0; 2198e5c31af7Sopenharmony_ci } 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci if (m_vs_id != 0) 2201e5c31af7Sopenharmony_ci { 2202e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 2203e5c31af7Sopenharmony_ci m_vs_id = 0; 2204e5c31af7Sopenharmony_ci } 2205e5c31af7Sopenharmony_ci 2206e5c31af7Sopenharmony_ci /* Release base class */ 2207e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 2208e5c31af7Sopenharmony_ci} 2209e5c31af7Sopenharmony_ci 2210e5c31af7Sopenharmony_ci/* Retrieves test-specific geometry shader source code. 2211e5c31af7Sopenharmony_ci * 2212e5c31af7Sopenharmony_ci * @return Requested string. 2213e5c31af7Sopenharmony_ci */ 2214e5c31af7Sopenharmony_cistd::string GeometryShaderMaxAtomicCountersTest::getGSCode() 2215e5c31af7Sopenharmony_ci{ 2216e5c31af7Sopenharmony_ci std::stringstream code_sstream; 2217e5c31af7Sopenharmony_ci 2218e5c31af7Sopenharmony_ci /* Form the GS */ 2219e5c31af7Sopenharmony_ci code_sstream << "${VERSION}\n" 2220e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 2221e5c31af7Sopenharmony_ci "\n" 2222e5c31af7Sopenharmony_ci "layout (points) in;\n" 2223e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 2224e5c31af7Sopenharmony_ci "\n" 2225e5c31af7Sopenharmony_ci "uniform int n_loop_iterations;\n" 2226e5c31af7Sopenharmony_ci "flat in int vertex_id[];\n" 2227e5c31af7Sopenharmony_ci "\n"; 2228e5c31af7Sopenharmony_ci 2229e5c31af7Sopenharmony_ci code_sstream << "layout(binding = 0) uniform atomic_uint acs[" << m_gl_max_geometry_atomic_counters_ext_value 2230e5c31af7Sopenharmony_ci << "];\n" 2231e5c31af7Sopenharmony_ci << "\n" 2232e5c31af7Sopenharmony_ci "void main()\n" 2233e5c31af7Sopenharmony_ci "{\n" 2234e5c31af7Sopenharmony_ci " for (int counter_id = 1;\n" 2235e5c31af7Sopenharmony_ci " counter_id <= n_loop_iterations;\n" 2236e5c31af7Sopenharmony_ci " ++counter_id)\n" 2237e5c31af7Sopenharmony_ci " {\n" 2238e5c31af7Sopenharmony_ci " if ((vertex_id[0] % counter_id) == 0)\n" 2239e5c31af7Sopenharmony_ci " {\n" 2240e5c31af7Sopenharmony_ci " atomicCounterIncrement(acs[counter_id - 1]);\n" 2241e5c31af7Sopenharmony_ci " }\n" 2242e5c31af7Sopenharmony_ci " }\n" 2243e5c31af7Sopenharmony_ci "\n" 2244e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 2245e5c31af7Sopenharmony_ci " EmitVertex();\n" 2246e5c31af7Sopenharmony_ci "}\n"; 2247e5c31af7Sopenharmony_ci 2248e5c31af7Sopenharmony_ci /* Form a specialized version of the GS source code */ 2249e5c31af7Sopenharmony_ci std::string gs_code = code_sstream.str(); 2250e5c31af7Sopenharmony_ci const char* gs_code_raw = gs_code.c_str(); 2251e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw); 2252e5c31af7Sopenharmony_ci 2253e5c31af7Sopenharmony_ci return gs_code_specialized; 2254e5c31af7Sopenharmony_ci} 2255e5c31af7Sopenharmony_ci 2256e5c31af7Sopenharmony_ci/** Executes the test. 2257e5c31af7Sopenharmony_ci * 2258e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 2259e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2260e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 2261e5c31af7Sopenharmony_ci **/ 2262e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderMaxAtomicCountersTest::iterate() 2263e5c31af7Sopenharmony_ci{ 2264e5c31af7Sopenharmony_ci /* Define Vertex Shader's code for the purpose of this test. */ 2265e5c31af7Sopenharmony_ci const char* vs_code = "${VERSION}\n" 2266e5c31af7Sopenharmony_ci "\n" 2267e5c31af7Sopenharmony_ci "flat out int vertex_id;\n" 2268e5c31af7Sopenharmony_ci "\n" 2269e5c31af7Sopenharmony_ci "void main()\n" 2270e5c31af7Sopenharmony_ci "{\n" 2271e5c31af7Sopenharmony_ci " vertex_id = gl_VertexID;\n" 2272e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 2273e5c31af7Sopenharmony_ci "}\n"; 2274e5c31af7Sopenharmony_ci 2275e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 2276e5c31af7Sopenharmony_ci glw::GLuint* initial_ac_data = DE_NULL; 2277e5c31af7Sopenharmony_ci const unsigned int n_draw_call_vertices = 4; 2278e5c31af7Sopenharmony_ci glw::GLint n_loop_iterations_uniform_location = -1; 2279e5c31af7Sopenharmony_ci glw::GLuint* ptrACBO_data = DE_NULL; 2280e5c31af7Sopenharmony_ci bool result = true; 2281e5c31af7Sopenharmony_ci 2282e5c31af7Sopenharmony_ci std::string fs_code_specialized = ""; 2283e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = DE_NULL; 2284e5c31af7Sopenharmony_ci std::string gs_code_specialized = ""; 2285e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = DE_NULL; 2286e5c31af7Sopenharmony_ci std::string vs_code_specialized = ""; 2287e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = DE_NULL; 2288e5c31af7Sopenharmony_ci 2289e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 2290e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 2291e5c31af7Sopenharmony_ci { 2292e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2293e5c31af7Sopenharmony_ci } 2294e5c31af7Sopenharmony_ci 2295e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2296e5c31af7Sopenharmony_ci 2297e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname value */ 2298e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &m_gl_max_geometry_atomic_counters_ext_value); 2299e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname"); 2300e5c31af7Sopenharmony_ci 2301e5c31af7Sopenharmony_ci /* Check if m_gl_max_atomic_counters_value is less than or equal zero. */ 2302e5c31af7Sopenharmony_ci if (m_gl_max_geometry_atomic_counters_ext_value <= 0) 2303e5c31af7Sopenharmony_ci { 2304e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT query value " 2305e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_atomic_counters_ext_value 2306e5c31af7Sopenharmony_ci << "]" 2307e5c31af7Sopenharmony_ci " is less than or equal to zero. Atomic Counters" 2308e5c31af7Sopenharmony_ci " in Geometry Shader are not supported." 2309e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2310e5c31af7Sopenharmony_ci 2311e5c31af7Sopenharmony_ci if (m_gl_max_geometry_atomic_counters_ext_value == 0) 2312e5c31af7Sopenharmony_ci { 2313e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT is 0"); 2314e5c31af7Sopenharmony_ci } 2315e5c31af7Sopenharmony_ci else 2316e5c31af7Sopenharmony_ci { 2317e5c31af7Sopenharmony_ci result = false; 2318e5c31af7Sopenharmony_ci goto end; 2319e5c31af7Sopenharmony_ci } 2320e5c31af7Sopenharmony_ci } 2321e5c31af7Sopenharmony_ci 2322e5c31af7Sopenharmony_ci /* Create a program object. */ 2323e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 2324e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 2325e5c31af7Sopenharmony_ci 2326e5c31af7Sopenharmony_ci /* Create shader objects. */ 2327e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 2328e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 2329e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 2330e5c31af7Sopenharmony_ci 2331e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 2332e5c31af7Sopenharmony_ci 2333e5c31af7Sopenharmony_ci /* Try to link the test program object */ 2334e5c31af7Sopenharmony_ci fs_code_specialized = specializeShader(1, &minimal_fs_code); 2335e5c31af7Sopenharmony_ci fs_code_specialized_raw = fs_code_specialized.c_str(); 2336e5c31af7Sopenharmony_ci 2337e5c31af7Sopenharmony_ci gs_code_specialized = getGSCode(); 2338e5c31af7Sopenharmony_ci gs_code_specialized_raw = gs_code_specialized.c_str(); 2339e5c31af7Sopenharmony_ci 2340e5c31af7Sopenharmony_ci vs_code_specialized = specializeShader(1, &vs_code); 2341e5c31af7Sopenharmony_ci vs_code_specialized_raw = vs_code_specialized.c_str(); 2342e5c31af7Sopenharmony_ci 2343e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 2344e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */ 2345e5c31af7Sopenharmony_ci &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */ 2346e5c31af7Sopenharmony_ci &fs_code_specialized_raw, &has_shader_compilation_failed)) 2347e5c31af7Sopenharmony_ci { 2348e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage; 2349e5c31af7Sopenharmony_ci 2350e5c31af7Sopenharmony_ci result = false; 2351e5c31af7Sopenharmony_ci goto end; 2352e5c31af7Sopenharmony_ci } 2353e5c31af7Sopenharmony_ci 2354e5c31af7Sopenharmony_ci /* Create Atomic Counter Buffer Objects. */ 2355e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_acbo_id); 2356e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 2357e5c31af7Sopenharmony_ci 2358e5c31af7Sopenharmony_ci /* Prepare initial data - zeroes - to fill the Atomic Counter Buffer Object. */ 2359e5c31af7Sopenharmony_ci initial_ac_data = new glw::GLuint[m_gl_max_geometry_atomic_counters_ext_value]; 2360e5c31af7Sopenharmony_ci memset(initial_ac_data, 0, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value); 2361e5c31af7Sopenharmony_ci 2362e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_id); 2363e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname."); 2364e5c31af7Sopenharmony_ci 2365e5c31af7Sopenharmony_ci gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value, NULL, 2366e5c31af7Sopenharmony_ci GL_DYNAMIC_COPY); 2367e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 2368e5c31af7Sopenharmony_ci 2369e5c31af7Sopenharmony_ci gl.bufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/, 2370e5c31af7Sopenharmony_ci sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value, 2371e5c31af7Sopenharmony_ci initial_ac_data /*initialize with zeroes*/); 2372e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed."); 2373e5c31af7Sopenharmony_ci 2374e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0 /*binding index*/, m_acbo_id /*buffer*/); 2375e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed."); 2376e5c31af7Sopenharmony_ci 2377e5c31af7Sopenharmony_ci /* Configure VAO. */ 2378e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 2379e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 2380e5c31af7Sopenharmony_ci 2381e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 2382e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 2383e5c31af7Sopenharmony_ci 2384e5c31af7Sopenharmony_ci /* Use program. */ 2385e5c31af7Sopenharmony_ci n_loop_iterations_uniform_location = gl.getUniformLocation(m_po_id, "n_loop_iterations"); 2386e5c31af7Sopenharmony_ci 2387e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed."); 2388e5c31af7Sopenharmony_ci if (n_loop_iterations_uniform_location == -1) 2389e5c31af7Sopenharmony_ci { 2390e5c31af7Sopenharmony_ci TCU_FAIL("n_loop_iterations uniform is considered inactive"); 2391e5c31af7Sopenharmony_ci } 2392e5c31af7Sopenharmony_ci else 2393e5c31af7Sopenharmony_ci { 2394e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 2395e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 2396e5c31af7Sopenharmony_ci 2397e5c31af7Sopenharmony_ci gl.uniform1i(n_loop_iterations_uniform_location, m_gl_max_geometry_atomic_counters_ext_value); 2398e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed."); 2399e5c31af7Sopenharmony_ci } 2400e5c31af7Sopenharmony_ci 2401e5c31af7Sopenharmony_ci /* Issue the draw call */ 2402e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, n_draw_call_vertices); 2403e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname."); 2404e5c31af7Sopenharmony_ci 2405e5c31af7Sopenharmony_ci /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */ 2406e5c31af7Sopenharmony_ci ptrACBO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/, 2407e5c31af7Sopenharmony_ci sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value, 2408e5c31af7Sopenharmony_ci GL_MAP_READ_BIT); 2409e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 2410e5c31af7Sopenharmony_ci 2411e5c31af7Sopenharmony_ci for (glw::GLint n_ac = 0; n_ac < m_gl_max_geometry_atomic_counters_ext_value; ++n_ac) 2412e5c31af7Sopenharmony_ci { 2413e5c31af7Sopenharmony_ci unsigned int expected_value = 0; 2414e5c31af7Sopenharmony_ci 2415e5c31af7Sopenharmony_ci for (unsigned int n_draw_call_vertex = 0; n_draw_call_vertex < n_draw_call_vertices; ++n_draw_call_vertex) 2416e5c31af7Sopenharmony_ci { 2417e5c31af7Sopenharmony_ci if ((n_draw_call_vertex % (n_ac + 1)) == 0) 2418e5c31af7Sopenharmony_ci { 2419e5c31af7Sopenharmony_ci ++expected_value; 2420e5c31af7Sopenharmony_ci } 2421e5c31af7Sopenharmony_ci } 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ci if (ptrACBO_data[n_ac] != expected_value) 2424e5c31af7Sopenharmony_ci { 2425e5c31af7Sopenharmony_ci result = false; 2426e5c31af7Sopenharmony_ci break; 2427e5c31af7Sopenharmony_ci } 2428e5c31af7Sopenharmony_ci } 2429e5c31af7Sopenharmony_ci 2430e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 2431e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 2432e5c31af7Sopenharmony_ci 2433e5c31af7Sopenharmony_ci ptrACBO_data = NULL; 2434e5c31af7Sopenharmony_ci 2435e5c31af7Sopenharmony_ciend: 2436e5c31af7Sopenharmony_ci if (result) 2437e5c31af7Sopenharmony_ci { 2438e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2439e5c31af7Sopenharmony_ci } 2440e5c31af7Sopenharmony_ci else 2441e5c31af7Sopenharmony_ci { 2442e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2443e5c31af7Sopenharmony_ci } 2444e5c31af7Sopenharmony_ci 2445e5c31af7Sopenharmony_ci return STOP; 2446e5c31af7Sopenharmony_ci} 2447e5c31af7Sopenharmony_ci 2448e5c31af7Sopenharmony_ci/** Constructor 2449e5c31af7Sopenharmony_ci * 2450e5c31af7Sopenharmony_ci * @param context Test context 2451e5c31af7Sopenharmony_ci * @param extParams Not used. 2452e5c31af7Sopenharmony_ci * @param name Test case's name 2453e5c31af7Sopenharmony_ci * @param description Test case's description 2454e5c31af7Sopenharmony_ci **/ 2455e5c31af7Sopenharmony_ciGeometryShaderMaxAtomicCounterBuffersTest::GeometryShaderMaxAtomicCounterBuffersTest(Context& context, 2456e5c31af7Sopenharmony_ci const ExtParameters& extParams, 2457e5c31af7Sopenharmony_ci const char* name, 2458e5c31af7Sopenharmony_ci const char* description) 2459e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 2460e5c31af7Sopenharmony_ci , m_acbo_ids(NULL) 2461e5c31af7Sopenharmony_ci , m_fs_id(0) 2462e5c31af7Sopenharmony_ci , m_gl_max_atomic_counter_buffer_bindings_value(0) 2463e5c31af7Sopenharmony_ci , m_gl_max_geometry_atomic_counter_buffers_ext_value(0) 2464e5c31af7Sopenharmony_ci , m_gs_id(0) 2465e5c31af7Sopenharmony_ci , m_po_id(0) 2466e5c31af7Sopenharmony_ci , m_vao_id(0) 2467e5c31af7Sopenharmony_ci , m_vs_id(0) 2468e5c31af7Sopenharmony_ci{ 2469e5c31af7Sopenharmony_ci} 2470e5c31af7Sopenharmony_ci 2471e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 2472e5c31af7Sopenharmony_civoid GeometryShaderMaxAtomicCounterBuffersTest::deinit() 2473e5c31af7Sopenharmony_ci{ 2474e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2475e5c31af7Sopenharmony_ci 2476e5c31af7Sopenharmony_ci if (m_acbo_ids != NULL) 2477e5c31af7Sopenharmony_ci { 2478e5c31af7Sopenharmony_ci if (m_gl_max_geometry_atomic_counter_buffers_ext_value > 0) 2479e5c31af7Sopenharmony_ci { 2480e5c31af7Sopenharmony_ci gl.deleteBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids); 2481e5c31af7Sopenharmony_ci 2482e5c31af7Sopenharmony_ci delete[] m_acbo_ids; 2483e5c31af7Sopenharmony_ci m_acbo_ids = NULL; 2484e5c31af7Sopenharmony_ci } 2485e5c31af7Sopenharmony_ci } 2486e5c31af7Sopenharmony_ci 2487e5c31af7Sopenharmony_ci if (m_fs_id != 0) 2488e5c31af7Sopenharmony_ci { 2489e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 2490e5c31af7Sopenharmony_ci m_fs_id = 0; 2491e5c31af7Sopenharmony_ci } 2492e5c31af7Sopenharmony_ci 2493e5c31af7Sopenharmony_ci if (m_gs_id != 0) 2494e5c31af7Sopenharmony_ci { 2495e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 2496e5c31af7Sopenharmony_ci m_gs_id = 0; 2497e5c31af7Sopenharmony_ci } 2498e5c31af7Sopenharmony_ci 2499e5c31af7Sopenharmony_ci if (m_po_id != 0) 2500e5c31af7Sopenharmony_ci { 2501e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 2502e5c31af7Sopenharmony_ci m_po_id = 0; 2503e5c31af7Sopenharmony_ci } 2504e5c31af7Sopenharmony_ci 2505e5c31af7Sopenharmony_ci if (m_vao_id != 0) 2506e5c31af7Sopenharmony_ci { 2507e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 2508e5c31af7Sopenharmony_ci m_vao_id = 0; 2509e5c31af7Sopenharmony_ci } 2510e5c31af7Sopenharmony_ci 2511e5c31af7Sopenharmony_ci if (m_vs_id != 0) 2512e5c31af7Sopenharmony_ci { 2513e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 2514e5c31af7Sopenharmony_ci m_vs_id = 0; 2515e5c31af7Sopenharmony_ci } 2516e5c31af7Sopenharmony_ci 2517e5c31af7Sopenharmony_ci /* Release base class */ 2518e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 2519e5c31af7Sopenharmony_ci} 2520e5c31af7Sopenharmony_ci 2521e5c31af7Sopenharmony_ci/* Retrieves test-specific geometry shader source code. 2522e5c31af7Sopenharmony_ci * 2523e5c31af7Sopenharmony_ci * @return Requested string. 2524e5c31af7Sopenharmony_ci */ 2525e5c31af7Sopenharmony_cistd::string GeometryShaderMaxAtomicCounterBuffersTest::getGSCode() 2526e5c31af7Sopenharmony_ci{ 2527e5c31af7Sopenharmony_ci std::stringstream code_sstream; 2528e5c31af7Sopenharmony_ci 2529e5c31af7Sopenharmony_ci /* Form the GS */ 2530e5c31af7Sopenharmony_ci code_sstream << "${VERSION}\n" 2531e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 2532e5c31af7Sopenharmony_ci "\n" 2533e5c31af7Sopenharmony_ci "layout (points) in;\n" 2534e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 2535e5c31af7Sopenharmony_ci "\n" 2536e5c31af7Sopenharmony_ci "flat in int vertex_id[];\n" 2537e5c31af7Sopenharmony_ci "\n"; 2538e5c31af7Sopenharmony_ci 2539e5c31af7Sopenharmony_ci for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac) 2540e5c31af7Sopenharmony_ci { 2541e5c31af7Sopenharmony_ci code_sstream << "layout(binding = " << n_ac << ") uniform atomic_uint ac" << n_ac << ";\n"; 2542e5c31af7Sopenharmony_ci } 2543e5c31af7Sopenharmony_ci 2544e5c31af7Sopenharmony_ci code_sstream << "\n" 2545e5c31af7Sopenharmony_ci "void main()\n" 2546e5c31af7Sopenharmony_ci "{\n" 2547e5c31af7Sopenharmony_ci " for(int counter_id = 1; counter_id <= " 2548e5c31af7Sopenharmony_ci << m_gl_max_geometry_atomic_counter_buffers_ext_value 2549e5c31af7Sopenharmony_ci << "; ++counter_id)\n" 2550e5c31af7Sopenharmony_ci " {\n" 2551e5c31af7Sopenharmony_ci " if((vertex_id[0] % counter_id) == 0)\n" 2552e5c31af7Sopenharmony_ci " {\n"; 2553e5c31af7Sopenharmony_ci 2554e5c31af7Sopenharmony_ci for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac) 2555e5c31af7Sopenharmony_ci { 2556e5c31af7Sopenharmony_ci code_sstream << " atomicCounterIncrement(ac" << n_ac << ");\n"; 2557e5c31af7Sopenharmony_ci } 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_ci code_sstream << " }\n" 2560e5c31af7Sopenharmony_ci " }\n"; 2561e5c31af7Sopenharmony_ci 2562e5c31af7Sopenharmony_ci code_sstream << "\n" 2563e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 2564e5c31af7Sopenharmony_ci " EmitVertex();\n" 2565e5c31af7Sopenharmony_ci "}\n"; 2566e5c31af7Sopenharmony_ci 2567e5c31af7Sopenharmony_ci /* Form a specialized version of the GS source code */ 2568e5c31af7Sopenharmony_ci std::string gs_code = code_sstream.str(); 2569e5c31af7Sopenharmony_ci const char* gs_code_raw = gs_code.c_str(); 2570e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw); 2571e5c31af7Sopenharmony_ci 2572e5c31af7Sopenharmony_ci return gs_code_specialized; 2573e5c31af7Sopenharmony_ci} 2574e5c31af7Sopenharmony_ci 2575e5c31af7Sopenharmony_ci/** Executes the test. 2576e5c31af7Sopenharmony_ci * 2577e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 2578e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2579e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 2580e5c31af7Sopenharmony_ci **/ 2581e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderMaxAtomicCounterBuffersTest::iterate() 2582e5c31af7Sopenharmony_ci{ 2583e5c31af7Sopenharmony_ci /* Define Vertex Shader's code for the purpose of this test. */ 2584e5c31af7Sopenharmony_ci const char* vs_code = "${VERSION}\n" 2585e5c31af7Sopenharmony_ci "\n" 2586e5c31af7Sopenharmony_ci "flat out int vertex_id;\n" 2587e5c31af7Sopenharmony_ci "\n" 2588e5c31af7Sopenharmony_ci "void main()\n" 2589e5c31af7Sopenharmony_ci "{\n" 2590e5c31af7Sopenharmony_ci " vertex_id = gl_VertexID;\n" 2591e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 2592e5c31af7Sopenharmony_ci "}\n"; 2593e5c31af7Sopenharmony_ci 2594e5c31af7Sopenharmony_ci unsigned int expected_value = 0; 2595e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2596e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 2597e5c31af7Sopenharmony_ci const glw::GLuint initial_ac_data = 0; 2598e5c31af7Sopenharmony_ci const glw::GLuint number_of_indices = 128 * m_gl_max_geometry_atomic_counter_buffers_ext_value; 2599e5c31af7Sopenharmony_ci bool result = true; 2600e5c31af7Sopenharmony_ci 2601e5c31af7Sopenharmony_ci std::string fs_code_specialized = ""; 2602e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = DE_NULL; 2603e5c31af7Sopenharmony_ci std::string gs_code_specialized = ""; 2604e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = DE_NULL; 2605e5c31af7Sopenharmony_ci std::string vs_code_specialized = ""; 2606e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = DE_NULL; 2607e5c31af7Sopenharmony_ci 2608e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 2609e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 2610e5c31af7Sopenharmony_ci { 2611e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2612e5c31af7Sopenharmony_ci } 2613e5c31af7Sopenharmony_ci 2614e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname value */ 2615e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, 2616e5c31af7Sopenharmony_ci &m_gl_max_geometry_atomic_counter_buffers_ext_value); 2617e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname"); 2618e5c31af7Sopenharmony_ci 2619e5c31af7Sopenharmony_ci /* Retrieve GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname value */ 2620e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &m_gl_max_atomic_counter_buffer_bindings_value); 2621e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname"); 2622e5c31af7Sopenharmony_ci 2623e5c31af7Sopenharmony_ci /* Check if m_gl_max_geometry_atomic_counter_buffers_ext_value is less than or equal zero. */ 2624e5c31af7Sopenharmony_ci if (m_gl_max_geometry_atomic_counter_buffers_ext_value <= 0) 2625e5c31af7Sopenharmony_ci { 2626e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value " 2627e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value 2628e5c31af7Sopenharmony_ci << "]" 2629e5c31af7Sopenharmony_ci " is less than or equal to zero. Atomic Counter Buffers" 2630e5c31af7Sopenharmony_ci " are not supported." 2631e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2632e5c31af7Sopenharmony_ci 2633e5c31af7Sopenharmony_ci if (m_gl_max_geometry_atomic_counter_buffers_ext_value == 0) 2634e5c31af7Sopenharmony_ci { 2635e5c31af7Sopenharmony_ci throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT is 0"); 2636e5c31af7Sopenharmony_ci } 2637e5c31af7Sopenharmony_ci else 2638e5c31af7Sopenharmony_ci { 2639e5c31af7Sopenharmony_ci result = false; 2640e5c31af7Sopenharmony_ci goto end; 2641e5c31af7Sopenharmony_ci } 2642e5c31af7Sopenharmony_ci } 2643e5c31af7Sopenharmony_ci 2644e5c31af7Sopenharmony_ci /* Check if m_gl_max_atomic_counter_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */ 2645e5c31af7Sopenharmony_ci if (m_gl_max_atomic_counter_buffer_bindings_value < m_gl_max_geometry_atomic_counter_buffers_ext_value) 2646e5c31af7Sopenharmony_ci { 2647e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value " 2648e5c31af7Sopenharmony_ci << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value 2649e5c31af7Sopenharmony_ci << "]" 2650e5c31af7Sopenharmony_ci " is greater than GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS query value " 2651e5c31af7Sopenharmony_ci "[" 2652e5c31af7Sopenharmony_ci << m_gl_max_atomic_counter_buffer_bindings_value << "]." << tcu::TestLog::EndMessage; 2653e5c31af7Sopenharmony_ci 2654e5c31af7Sopenharmony_ci result = false; 2655e5c31af7Sopenharmony_ci goto end; 2656e5c31af7Sopenharmony_ci } 2657e5c31af7Sopenharmony_ci 2658e5c31af7Sopenharmony_ci /* Create a program object. */ 2659e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 2660e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 2661e5c31af7Sopenharmony_ci 2662e5c31af7Sopenharmony_ci /* Create shader objects. */ 2663e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 2664e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 2665e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 2666e5c31af7Sopenharmony_ci 2667e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 2668e5c31af7Sopenharmony_ci 2669e5c31af7Sopenharmony_ci /* Try to link the test program object */ 2670e5c31af7Sopenharmony_ci fs_code_specialized = specializeShader(1, &minimal_fs_code); 2671e5c31af7Sopenharmony_ci fs_code_specialized_raw = fs_code_specialized.c_str(); 2672e5c31af7Sopenharmony_ci 2673e5c31af7Sopenharmony_ci gs_code_specialized = getGSCode(); 2674e5c31af7Sopenharmony_ci gs_code_specialized_raw = gs_code_specialized.c_str(); 2675e5c31af7Sopenharmony_ci 2676e5c31af7Sopenharmony_ci vs_code_specialized = specializeShader(1, &vs_code); 2677e5c31af7Sopenharmony_ci vs_code_specialized_raw = vs_code_specialized.c_str(); 2678e5c31af7Sopenharmony_ci 2679e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 2680e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */ 2681e5c31af7Sopenharmony_ci &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */ 2682e5c31af7Sopenharmony_ci &fs_code_specialized_raw, &has_shader_compilation_failed)) 2683e5c31af7Sopenharmony_ci { 2684e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage; 2685e5c31af7Sopenharmony_ci 2686e5c31af7Sopenharmony_ci result = false; 2687e5c31af7Sopenharmony_ci goto end; 2688e5c31af7Sopenharmony_ci } 2689e5c31af7Sopenharmony_ci 2690e5c31af7Sopenharmony_ci /* Create Atomic Counter Buffer Objects. */ 2691e5c31af7Sopenharmony_ci m_acbo_ids = new glw::GLuint[m_gl_max_geometry_atomic_counter_buffers_ext_value]; 2692e5c31af7Sopenharmony_ci 2693e5c31af7Sopenharmony_ci gl.genBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids); 2694e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed."); 2695e5c31af7Sopenharmony_ci 2696e5c31af7Sopenharmony_ci for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb) 2697e5c31af7Sopenharmony_ci { 2698e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]); 2699e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname."); 2700e5c31af7Sopenharmony_ci 2701e5c31af7Sopenharmony_ci gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint), &initial_ac_data /*initialize with zeroes*/, 2702e5c31af7Sopenharmony_ci GL_DYNAMIC_COPY); 2703e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed."); 2704e5c31af7Sopenharmony_ci 2705e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, n_acb /*binding index*/, m_acbo_ids[n_acb] /*buffer*/); 2706e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed."); 2707e5c31af7Sopenharmony_ci } 2708e5c31af7Sopenharmony_ci 2709e5c31af7Sopenharmony_ci /* Configure VAO. */ 2710e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 2711e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 2712e5c31af7Sopenharmony_ci 2713e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 2714e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 2715e5c31af7Sopenharmony_ci 2716e5c31af7Sopenharmony_ci /* Use program. */ 2717e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 2718e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 2719e5c31af7Sopenharmony_ci 2720e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*starting index*/, number_of_indices); 2721e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname."); 2722e5c31af7Sopenharmony_ci 2723e5c31af7Sopenharmony_ci /* Calculate expected value. */ 2724e5c31af7Sopenharmony_ci /* For each point being processed by Geometry Shader. */ 2725e5c31af7Sopenharmony_ci for (glw::GLuint vertex_id = 0; vertex_id < number_of_indices; ++vertex_id) 2726e5c31af7Sopenharmony_ci { 2727e5c31af7Sopenharmony_ci /* And for each atomic counter ID. */ 2728e5c31af7Sopenharmony_ci for (int atomic_counter_id = 1; atomic_counter_id <= m_gl_max_geometry_atomic_counter_buffers_ext_value; 2729e5c31af7Sopenharmony_ci ++atomic_counter_id) 2730e5c31af7Sopenharmony_ci { 2731e5c31af7Sopenharmony_ci /* Check if (vertex_id % atomic_counter_id) == 0. If it is true, increment expected_value. */ 2732e5c31af7Sopenharmony_ci if (vertex_id % atomic_counter_id == 0) 2733e5c31af7Sopenharmony_ci { 2734e5c31af7Sopenharmony_ci ++expected_value; 2735e5c31af7Sopenharmony_ci } 2736e5c31af7Sopenharmony_ci } 2737e5c31af7Sopenharmony_ci } 2738e5c31af7Sopenharmony_ci 2739e5c31af7Sopenharmony_ci /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */ 2740e5c31af7Sopenharmony_ci for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb) 2741e5c31af7Sopenharmony_ci { 2742e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]); 2743e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed."); 2744e5c31af7Sopenharmony_ci 2745e5c31af7Sopenharmony_ci glw::GLuint* ptrABO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/, 2746e5c31af7Sopenharmony_ci sizeof(glw::GLuint) /*length*/, GL_MAP_READ_BIT); 2747e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 2748e5c31af7Sopenharmony_ci 2749e5c31af7Sopenharmony_ci if (ptrABO_data[0] != expected_value) 2750e5c31af7Sopenharmony_ci { 2751e5c31af7Sopenharmony_ci result = false; 2752e5c31af7Sopenharmony_ci break; 2753e5c31af7Sopenharmony_ci } 2754e5c31af7Sopenharmony_ci 2755e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); 2756e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 2757e5c31af7Sopenharmony_ci 2758e5c31af7Sopenharmony_ci ptrABO_data = NULL; 2759e5c31af7Sopenharmony_ci } 2760e5c31af7Sopenharmony_ci 2761e5c31af7Sopenharmony_ciend: 2762e5c31af7Sopenharmony_ci if (result) 2763e5c31af7Sopenharmony_ci { 2764e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2765e5c31af7Sopenharmony_ci } 2766e5c31af7Sopenharmony_ci else 2767e5c31af7Sopenharmony_ci { 2768e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2769e5c31af7Sopenharmony_ci } 2770e5c31af7Sopenharmony_ci 2771e5c31af7Sopenharmony_ci return STOP; 2772e5c31af7Sopenharmony_ci} 2773e5c31af7Sopenharmony_ci 2774e5c31af7Sopenharmony_ci/** Constructor 2775e5c31af7Sopenharmony_ci * 2776e5c31af7Sopenharmony_ci * @param context Test context 2777e5c31af7Sopenharmony_ci * @param extParams Not used. 2778e5c31af7Sopenharmony_ci * @param name Test case's name 2779e5c31af7Sopenharmony_ci * @param description Test case's description 2780e5c31af7Sopenharmony_ci **/ 2781e5c31af7Sopenharmony_ciGeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest:: 2782e5c31af7Sopenharmony_ci GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest(Context& context, const ExtParameters& extParams, 2783e5c31af7Sopenharmony_ci const char* name, const char* description) 2784e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 2785e5c31af7Sopenharmony_ci , m_fs_id(0) 2786e5c31af7Sopenharmony_ci , m_fs_po_id(0) 2787e5c31af7Sopenharmony_ci , m_gs_id(0) 2788e5c31af7Sopenharmony_ci , m_gs_po_id(0) 2789e5c31af7Sopenharmony_ci , m_ppo_id(0) 2790e5c31af7Sopenharmony_ci , m_vao_id(0) 2791e5c31af7Sopenharmony_ci{ 2792e5c31af7Sopenharmony_ci} 2793e5c31af7Sopenharmony_ci 2794e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 2795e5c31af7Sopenharmony_civoid GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::deinit() 2796e5c31af7Sopenharmony_ci{ 2797e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2798e5c31af7Sopenharmony_ci 2799e5c31af7Sopenharmony_ci if (m_fs_id != 0) 2800e5c31af7Sopenharmony_ci { 2801e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 2802e5c31af7Sopenharmony_ci m_fs_id = 0; 2803e5c31af7Sopenharmony_ci } 2804e5c31af7Sopenharmony_ci 2805e5c31af7Sopenharmony_ci if (m_fs_po_id != 0) 2806e5c31af7Sopenharmony_ci { 2807e5c31af7Sopenharmony_ci gl.deleteProgram(m_fs_po_id); 2808e5c31af7Sopenharmony_ci m_fs_po_id = 0; 2809e5c31af7Sopenharmony_ci } 2810e5c31af7Sopenharmony_ci 2811e5c31af7Sopenharmony_ci if (m_gs_id != 0) 2812e5c31af7Sopenharmony_ci { 2813e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 2814e5c31af7Sopenharmony_ci m_gs_id = 0; 2815e5c31af7Sopenharmony_ci } 2816e5c31af7Sopenharmony_ci 2817e5c31af7Sopenharmony_ci if (m_gs_po_id != 0) 2818e5c31af7Sopenharmony_ci { 2819e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 2820e5c31af7Sopenharmony_ci m_gs_po_id = 0; 2821e5c31af7Sopenharmony_ci } 2822e5c31af7Sopenharmony_ci 2823e5c31af7Sopenharmony_ci if (m_ppo_id != 0) 2824e5c31af7Sopenharmony_ci { 2825e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_ppo_id); 2826e5c31af7Sopenharmony_ci m_ppo_id = 0; 2827e5c31af7Sopenharmony_ci } 2828e5c31af7Sopenharmony_ci 2829e5c31af7Sopenharmony_ci if (m_vao_id != 0) 2830e5c31af7Sopenharmony_ci { 2831e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 2832e5c31af7Sopenharmony_ci m_vao_id = 0; 2833e5c31af7Sopenharmony_ci } 2834e5c31af7Sopenharmony_ci 2835e5c31af7Sopenharmony_ci /* Release base class */ 2836e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 2837e5c31af7Sopenharmony_ci} 2838e5c31af7Sopenharmony_ci 2839e5c31af7Sopenharmony_ci/** Executes the test. 2840e5c31af7Sopenharmony_ci * 2841e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 2842e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 2843e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 2844e5c31af7Sopenharmony_ci **/ 2845e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::iterate() 2846e5c31af7Sopenharmony_ci{ 2847e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 2848e5c31af7Sopenharmony_ci bool result = true; 2849e5c31af7Sopenharmony_ci glw::GLenum error = GL_NO_ERROR; 2850e5c31af7Sopenharmony_ci 2851e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 2852e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 2853e5c31af7Sopenharmony_ci { 2854e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 2855e5c31af7Sopenharmony_ci } 2856e5c31af7Sopenharmony_ci 2857e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2858e5c31af7Sopenharmony_ci 2859e5c31af7Sopenharmony_ci /* Create separable program objects. */ 2860e5c31af7Sopenharmony_ci m_fs_po_id = gl.createProgram(); 2861e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 2862e5c31af7Sopenharmony_ci 2863e5c31af7Sopenharmony_ci gl.programParameteri(m_fs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 2864e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed."); 2865e5c31af7Sopenharmony_ci 2866e5c31af7Sopenharmony_ci m_gs_po_id = gl.createProgram(); 2867e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 2868e5c31af7Sopenharmony_ci 2869e5c31af7Sopenharmony_ci gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 2870e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed."); 2871e5c31af7Sopenharmony_ci 2872e5c31af7Sopenharmony_ci /* Create shader objects. */ 2873e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 2874e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 2875e5c31af7Sopenharmony_ci 2876e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 2877e5c31af7Sopenharmony_ci 2878e5c31af7Sopenharmony_ci /* Try to link the test program object */ 2879e5c31af7Sopenharmony_ci std::string fs_code_specialized = specializeShader(1, &minimal_fs_code); 2880e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = fs_code_specialized.c_str(); 2881e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, &minimal_gs_code); 2882e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = gs_code_specialized.c_str(); 2883e5c31af7Sopenharmony_ci 2884e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_fs_po_id, m_fs_id, 1, /* n_sh1_body_parts */ 2885e5c31af7Sopenharmony_ci &fs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */ 2886e5c31af7Sopenharmony_ci NULL, 0, 0, /* n_sh3_body_parts */ 2887e5c31af7Sopenharmony_ci NULL, &has_shader_compilation_failed)) 2888e5c31af7Sopenharmony_ci { 2889e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Fragment Shader Program object linking failed." 2890e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci result = false; 2893e5c31af7Sopenharmony_ci goto end; 2894e5c31af7Sopenharmony_ci } 2895e5c31af7Sopenharmony_ci 2896e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 2897e5c31af7Sopenharmony_ci &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */ 2898e5c31af7Sopenharmony_ci NULL, 0, 0, /* n_sh3_body_parts */ 2899e5c31af7Sopenharmony_ci NULL, &has_shader_compilation_failed)) 2900e5c31af7Sopenharmony_ci { 2901e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed." 2902e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2903e5c31af7Sopenharmony_ci 2904e5c31af7Sopenharmony_ci result = false; 2905e5c31af7Sopenharmony_ci goto end; 2906e5c31af7Sopenharmony_ci } 2907e5c31af7Sopenharmony_ci 2908e5c31af7Sopenharmony_ci /* Configure Pipeline Object. */ 2909e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &m_ppo_id); 2910e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed."); 2911e5c31af7Sopenharmony_ci 2912e5c31af7Sopenharmony_ci gl.useProgramStages(m_ppo_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id); 2913e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 2914e5c31af7Sopenharmony_ci 2915e5c31af7Sopenharmony_ci gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id); 2916e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed."); 2917e5c31af7Sopenharmony_ci 2918e5c31af7Sopenharmony_ci /* Configure VAO. */ 2919e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 2920e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 2921e5c31af7Sopenharmony_ci 2922e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 2923e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 2924e5c31af7Sopenharmony_ci 2925e5c31af7Sopenharmony_ci /* Use Program Pipeline Object. */ 2926e5c31af7Sopenharmony_ci gl.bindProgramPipeline(m_ppo_id); 2927e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed."); 2928e5c31af7Sopenharmony_ci 2929e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/); 2930e5c31af7Sopenharmony_ci 2931e5c31af7Sopenharmony_ci error = gl.getError(); 2932e5c31af7Sopenharmony_ci 2933e5c31af7Sopenharmony_ci /* Check if correct error was generated. */ 2934e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != error) 2935e5c31af7Sopenharmony_ci { 2936e5c31af7Sopenharmony_ci result = false; 2937e5c31af7Sopenharmony_ci 2938e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated." 2939e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2940e5c31af7Sopenharmony_ci } 2941e5c31af7Sopenharmony_ci 2942e5c31af7Sopenharmony_ciend: 2943e5c31af7Sopenharmony_ci if (result) 2944e5c31af7Sopenharmony_ci { 2945e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2946e5c31af7Sopenharmony_ci } 2947e5c31af7Sopenharmony_ci else 2948e5c31af7Sopenharmony_ci { 2949e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2950e5c31af7Sopenharmony_ci } 2951e5c31af7Sopenharmony_ci 2952e5c31af7Sopenharmony_ci return STOP; 2953e5c31af7Sopenharmony_ci} 2954e5c31af7Sopenharmony_ci 2955e5c31af7Sopenharmony_ci/** Constructor 2956e5c31af7Sopenharmony_ci * 2957e5c31af7Sopenharmony_ci * @param context Test context 2958e5c31af7Sopenharmony_ci * @param extParams Not used. 2959e5c31af7Sopenharmony_ci * @param name Test case's name 2960e5c31af7Sopenharmony_ci * @param description Test case's description 2961e5c31af7Sopenharmony_ci **/ 2962e5c31af7Sopenharmony_ciGeometryShaderIncompatibleDrawCallModeTest::GeometryShaderIncompatibleDrawCallModeTest(Context& context, 2963e5c31af7Sopenharmony_ci const ExtParameters& extParams, 2964e5c31af7Sopenharmony_ci const char* name, 2965e5c31af7Sopenharmony_ci const char* description) 2966e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 2967e5c31af7Sopenharmony_ci , m_fs_id(0) 2968e5c31af7Sopenharmony_ci , m_gs_ids(NULL) 2969e5c31af7Sopenharmony_ci , m_number_of_gs(5 /*taken from test spec*/) 2970e5c31af7Sopenharmony_ci , m_po_ids(NULL) 2971e5c31af7Sopenharmony_ci{ 2972e5c31af7Sopenharmony_ci m_vao_id = 0; 2973e5c31af7Sopenharmony_ci m_vs_id = 0; 2974e5c31af7Sopenharmony_ci} 2975e5c31af7Sopenharmony_ci 2976e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 2977e5c31af7Sopenharmony_civoid GeometryShaderIncompatibleDrawCallModeTest::deinit() 2978e5c31af7Sopenharmony_ci{ 2979e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2980e5c31af7Sopenharmony_ci 2981e5c31af7Sopenharmony_ci if (m_fs_id != 0) 2982e5c31af7Sopenharmony_ci { 2983e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 2984e5c31af7Sopenharmony_ci m_fs_id = 0; 2985e5c31af7Sopenharmony_ci } 2986e5c31af7Sopenharmony_ci 2987e5c31af7Sopenharmony_ci if (m_gs_ids != 0) 2988e5c31af7Sopenharmony_ci { 2989e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 2990e5c31af7Sopenharmony_ci { 2991e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_ids[i]); 2992e5c31af7Sopenharmony_ci m_gs_ids[i] = 0; 2993e5c31af7Sopenharmony_ci } 2994e5c31af7Sopenharmony_ci 2995e5c31af7Sopenharmony_ci delete[] m_gs_ids; 2996e5c31af7Sopenharmony_ci m_gs_ids = NULL; 2997e5c31af7Sopenharmony_ci } 2998e5c31af7Sopenharmony_ci 2999e5c31af7Sopenharmony_ci if (m_po_ids != 0) 3000e5c31af7Sopenharmony_ci { 3001e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3002e5c31af7Sopenharmony_ci { 3003e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_ids[i]); 3004e5c31af7Sopenharmony_ci m_po_ids[i] = 0; 3005e5c31af7Sopenharmony_ci } 3006e5c31af7Sopenharmony_ci 3007e5c31af7Sopenharmony_ci delete[] m_po_ids; 3008e5c31af7Sopenharmony_ci m_po_ids = NULL; 3009e5c31af7Sopenharmony_ci } 3010e5c31af7Sopenharmony_ci 3011e5c31af7Sopenharmony_ci if (m_vao_id != 0) 3012e5c31af7Sopenharmony_ci { 3013e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 3014e5c31af7Sopenharmony_ci m_vao_id = 0; 3015e5c31af7Sopenharmony_ci } 3016e5c31af7Sopenharmony_ci 3017e5c31af7Sopenharmony_ci if (m_vs_id != 0) 3018e5c31af7Sopenharmony_ci { 3019e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 3020e5c31af7Sopenharmony_ci m_vs_id = 0; 3021e5c31af7Sopenharmony_ci } 3022e5c31af7Sopenharmony_ci 3023e5c31af7Sopenharmony_ci /* Release base class */ 3024e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 3025e5c31af7Sopenharmony_ci} 3026e5c31af7Sopenharmony_ci 3027e5c31af7Sopenharmony_ci/** Executes the test. 3028e5c31af7Sopenharmony_ci * 3029e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 3030e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 3031e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 3032e5c31af7Sopenharmony_ci **/ 3033e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderIncompatibleDrawCallModeTest::iterate() 3034e5c31af7Sopenharmony_ci{ 3035e5c31af7Sopenharmony_ci /* Define 5 Geometry Shaders for purpose of this test. */ 3036e5c31af7Sopenharmony_ci const char* gs_code_points = "${VERSION}\n" 3037e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3038e5c31af7Sopenharmony_ci "\n" 3039e5c31af7Sopenharmony_ci "layout (points) in;\n" 3040e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3041e5c31af7Sopenharmony_ci "\n" 3042e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3043e5c31af7Sopenharmony_ci "\n" 3044e5c31af7Sopenharmony_ci "void main()\n" 3045e5c31af7Sopenharmony_ci "{\n" 3046e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3047e5c31af7Sopenharmony_ci " EmitVertex();\n" 3048e5c31af7Sopenharmony_ci "}\n"; 3049e5c31af7Sopenharmony_ci 3050e5c31af7Sopenharmony_ci const char* gs_code_lines = "${VERSION}\n" 3051e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3052e5c31af7Sopenharmony_ci "\n" 3053e5c31af7Sopenharmony_ci "layout (lines) in;\n" 3054e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3055e5c31af7Sopenharmony_ci "\n" 3056e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3057e5c31af7Sopenharmony_ci "\n" 3058e5c31af7Sopenharmony_ci "void main()\n" 3059e5c31af7Sopenharmony_ci "{\n" 3060e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3061e5c31af7Sopenharmony_ci " EmitVertex();\n" 3062e5c31af7Sopenharmony_ci "}\n"; 3063e5c31af7Sopenharmony_ci 3064e5c31af7Sopenharmony_ci const char* gs_code_lines_adjacency = "${VERSION}\n" 3065e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3066e5c31af7Sopenharmony_ci "\n" 3067e5c31af7Sopenharmony_ci "layout (lines_adjacency) in;\n" 3068e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3069e5c31af7Sopenharmony_ci "\n" 3070e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3071e5c31af7Sopenharmony_ci "\n" 3072e5c31af7Sopenharmony_ci "void main()\n" 3073e5c31af7Sopenharmony_ci "{\n" 3074e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3075e5c31af7Sopenharmony_ci " EmitVertex();\n" 3076e5c31af7Sopenharmony_ci "}\n"; 3077e5c31af7Sopenharmony_ci 3078e5c31af7Sopenharmony_ci const char* gs_code_triangles = "${VERSION}\n" 3079e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3080e5c31af7Sopenharmony_ci "\n" 3081e5c31af7Sopenharmony_ci "layout (triangles) in;\n" 3082e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3083e5c31af7Sopenharmony_ci "\n" 3084e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3085e5c31af7Sopenharmony_ci "\n" 3086e5c31af7Sopenharmony_ci "void main()\n" 3087e5c31af7Sopenharmony_ci "{\n" 3088e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3089e5c31af7Sopenharmony_ci " EmitVertex();\n" 3090e5c31af7Sopenharmony_ci "}\n"; 3091e5c31af7Sopenharmony_ci 3092e5c31af7Sopenharmony_ci const char* gs_code_triangles_adjacency = "${VERSION}\n" 3093e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3094e5c31af7Sopenharmony_ci "\n" 3095e5c31af7Sopenharmony_ci "layout (triangles_adjacency) in;\n" 3096e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3097e5c31af7Sopenharmony_ci "\n" 3098e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3099e5c31af7Sopenharmony_ci "\n" 3100e5c31af7Sopenharmony_ci "void main()\n" 3101e5c31af7Sopenharmony_ci "{\n" 3102e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3103e5c31af7Sopenharmony_ci " EmitVertex();\n" 3104e5c31af7Sopenharmony_ci "}\n"; 3105e5c31af7Sopenharmony_ci 3106e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 3107e5c31af7Sopenharmony_ci bool result = true; 3108e5c31af7Sopenharmony_ci 3109e5c31af7Sopenharmony_ci m_gs_ids = new glw::GLuint[m_number_of_gs]; 3110e5c31af7Sopenharmony_ci m_po_ids = new glw::GLuint[m_number_of_gs]; 3111e5c31af7Sopenharmony_ci 3112e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 3113e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 3114e5c31af7Sopenharmony_ci { 3115e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 3116e5c31af7Sopenharmony_ci } 3117e5c31af7Sopenharmony_ci 3118e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3119e5c31af7Sopenharmony_ci 3120e5c31af7Sopenharmony_ci /* Create program objects & geometry shader objects. */ 3121e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3122e5c31af7Sopenharmony_ci { 3123e5c31af7Sopenharmony_ci m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER); 3124e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 3125e5c31af7Sopenharmony_ci 3126e5c31af7Sopenharmony_ci m_po_ids[i] = gl.createProgram(); 3127e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 3128e5c31af7Sopenharmony_ci } 3129e5c31af7Sopenharmony_ci 3130e5c31af7Sopenharmony_ci /* Create shader object. */ 3131e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 3132e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 3133e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 3134e5c31af7Sopenharmony_ci 3135e5c31af7Sopenharmony_ci /* Try to link the test program object */ 3136e5c31af7Sopenharmony_ci std::string fs_code_specialized = specializeShader(1, &minimal_fs_code); 3137e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = fs_code_specialized.c_str(); 3138e5c31af7Sopenharmony_ci 3139e5c31af7Sopenharmony_ci std::string gs_codes_specialized[] = { specializeShader(1, &gs_code_points), specializeShader(1, &gs_code_lines), 3140e5c31af7Sopenharmony_ci specializeShader(1, &gs_code_lines_adjacency), 3141e5c31af7Sopenharmony_ci specializeShader(1, &gs_code_triangles), 3142e5c31af7Sopenharmony_ci specializeShader(1, &gs_code_triangles_adjacency) }; 3143e5c31af7Sopenharmony_ci 3144e5c31af7Sopenharmony_ci const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str(), 3145e5c31af7Sopenharmony_ci gs_codes_specialized[2].c_str(), gs_codes_specialized[3].c_str(), 3146e5c31af7Sopenharmony_ci gs_codes_specialized[4].c_str() }; 3147e5c31af7Sopenharmony_ci std::string vs_code_specialized = specializeShader(1, &minimal_vs_code); 3148e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = vs_code_specialized.c_str(); 3149e5c31af7Sopenharmony_ci 3150e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3151e5c31af7Sopenharmony_ci { 3152e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */ 3153e5c31af7Sopenharmony_ci &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */ 3154e5c31af7Sopenharmony_ci &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */ 3155e5c31af7Sopenharmony_ci &vs_code_specialized_raw, &has_shader_compilation_failed)) 3156e5c31af7Sopenharmony_ci { 3157e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = " 3158e5c31af7Sopenharmony_ci << "[" << i << "]." << tcu::TestLog::EndMessage; 3159e5c31af7Sopenharmony_ci 3160e5c31af7Sopenharmony_ci result = false; 3161e5c31af7Sopenharmony_ci break; 3162e5c31af7Sopenharmony_ci } 3163e5c31af7Sopenharmony_ci } 3164e5c31af7Sopenharmony_ci 3165e5c31af7Sopenharmony_ci if (result) 3166e5c31af7Sopenharmony_ci { 3167e5c31af7Sopenharmony_ci /* Configure VAO. */ 3168e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 3169e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 3170e5c31af7Sopenharmony_ci 3171e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 3172e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 3173e5c31af7Sopenharmony_ci 3174e5c31af7Sopenharmony_ci for (glw::GLuint po = 0; po < m_number_of_gs; ++po) 3175e5c31af7Sopenharmony_ci { 3176e5c31af7Sopenharmony_ci /* Use Program Object. */ 3177e5c31af7Sopenharmony_ci gl.useProgram(m_po_ids[po]); 3178e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 3179e5c31af7Sopenharmony_ci 3180e5c31af7Sopenharmony_ci if (po != 0) 3181e5c31af7Sopenharmony_ci { 3182e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/); 3183e5c31af7Sopenharmony_ci 3184e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3185e5c31af7Sopenharmony_ci { 3186e5c31af7Sopenharmony_ci result = false; 3187e5c31af7Sopenharmony_ci 3188e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3189e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3190e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3191e5c31af7Sopenharmony_ci 3192e5c31af7Sopenharmony_ci break; 3193e5c31af7Sopenharmony_ci } 3194e5c31af7Sopenharmony_ci } 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci if (po != 1) 3197e5c31af7Sopenharmony_ci { 3198e5c31af7Sopenharmony_ci gl.drawArrays(GL_LINES, 0 /*starting index*/, 2 /*number of indices*/); 3199e5c31af7Sopenharmony_ci 3200e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3201e5c31af7Sopenharmony_ci { 3202e5c31af7Sopenharmony_ci result = false; 3203e5c31af7Sopenharmony_ci 3204e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3205e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3206e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3207e5c31af7Sopenharmony_ci 3208e5c31af7Sopenharmony_ci break; 3209e5c31af7Sopenharmony_ci } 3210e5c31af7Sopenharmony_ci 3211e5c31af7Sopenharmony_ci gl.drawArrays(GL_LINE_LOOP, 0 /*starting index*/, 2 /*number of indices*/); 3212e5c31af7Sopenharmony_ci 3213e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3214e5c31af7Sopenharmony_ci { 3215e5c31af7Sopenharmony_ci result = false; 3216e5c31af7Sopenharmony_ci 3217e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3218e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3219e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3220e5c31af7Sopenharmony_ci 3221e5c31af7Sopenharmony_ci break; 3222e5c31af7Sopenharmony_ci } 3223e5c31af7Sopenharmony_ci 3224e5c31af7Sopenharmony_ci gl.drawArrays(GL_LINE_STRIP, 0 /*starting index*/, 2 /*number of indices*/); 3225e5c31af7Sopenharmony_ci 3226e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3227e5c31af7Sopenharmony_ci { 3228e5c31af7Sopenharmony_ci result = false; 3229e5c31af7Sopenharmony_ci 3230e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3231e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3232e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3233e5c31af7Sopenharmony_ci 3234e5c31af7Sopenharmony_ci break; 3235e5c31af7Sopenharmony_ci } 3236e5c31af7Sopenharmony_ci } 3237e5c31af7Sopenharmony_ci 3238e5c31af7Sopenharmony_ci if (po != 2) 3239e5c31af7Sopenharmony_ci { 3240e5c31af7Sopenharmony_ci gl.drawArrays(GL_LINES_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/); 3241e5c31af7Sopenharmony_ci 3242e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3243e5c31af7Sopenharmony_ci { 3244e5c31af7Sopenharmony_ci result = false; 3245e5c31af7Sopenharmony_ci 3246e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3247e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3248e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3249e5c31af7Sopenharmony_ci 3250e5c31af7Sopenharmony_ci break; 3251e5c31af7Sopenharmony_ci } 3252e5c31af7Sopenharmony_ci 3253e5c31af7Sopenharmony_ci gl.drawArrays(GL_LINE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/); 3254e5c31af7Sopenharmony_ci 3255e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3256e5c31af7Sopenharmony_ci { 3257e5c31af7Sopenharmony_ci result = false; 3258e5c31af7Sopenharmony_ci 3259e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3260e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3261e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3262e5c31af7Sopenharmony_ci 3263e5c31af7Sopenharmony_ci break; 3264e5c31af7Sopenharmony_ci } 3265e5c31af7Sopenharmony_ci } 3266e5c31af7Sopenharmony_ci 3267e5c31af7Sopenharmony_ci if (po != 3) 3268e5c31af7Sopenharmony_ci { 3269e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLES, 0 /*starting index*/, 3 /*number of indices*/); 3270e5c31af7Sopenharmony_ci 3271e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3272e5c31af7Sopenharmony_ci { 3273e5c31af7Sopenharmony_ci result = false; 3274e5c31af7Sopenharmony_ci 3275e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3276e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3277e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3278e5c31af7Sopenharmony_ci 3279e5c31af7Sopenharmony_ci break; 3280e5c31af7Sopenharmony_ci } 3281e5c31af7Sopenharmony_ci 3282e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLE_FAN, 0 /*starting index*/, 3 /*number of indices*/); 3283e5c31af7Sopenharmony_ci 3284e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3285e5c31af7Sopenharmony_ci { 3286e5c31af7Sopenharmony_ci result = false; 3287e5c31af7Sopenharmony_ci 3288e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3289e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3290e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3291e5c31af7Sopenharmony_ci 3292e5c31af7Sopenharmony_ci break; 3293e5c31af7Sopenharmony_ci } 3294e5c31af7Sopenharmony_ci 3295e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLE_STRIP, 0 /*starting index*/, 3 /*number of indices*/); 3296e5c31af7Sopenharmony_ci 3297e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3298e5c31af7Sopenharmony_ci { 3299e5c31af7Sopenharmony_ci result = false; 3300e5c31af7Sopenharmony_ci 3301e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3302e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3303e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3304e5c31af7Sopenharmony_ci 3305e5c31af7Sopenharmony_ci break; 3306e5c31af7Sopenharmony_ci } 3307e5c31af7Sopenharmony_ci } 3308e5c31af7Sopenharmony_ci 3309e5c31af7Sopenharmony_ci if (po != 4) 3310e5c31af7Sopenharmony_ci { 3311e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLES_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/); 3312e5c31af7Sopenharmony_ci 3313e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3314e5c31af7Sopenharmony_ci { 3315e5c31af7Sopenharmony_ci result = false; 3316e5c31af7Sopenharmony_ci 3317e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3318e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3319e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3320e5c31af7Sopenharmony_ci 3321e5c31af7Sopenharmony_ci break; 3322e5c31af7Sopenharmony_ci } 3323e5c31af7Sopenharmony_ci 3324e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/); 3325e5c31af7Sopenharmony_ci 3326e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != gl.getError()) 3327e5c31af7Sopenharmony_ci { 3328e5c31af7Sopenharmony_ci result = false; 3329e5c31af7Sopenharmony_ci 3330e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 3331e5c31af7Sopenharmony_ci << "Error different than GL_INVALID_OPEARATION was generated." 3332e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3333e5c31af7Sopenharmony_ci 3334e5c31af7Sopenharmony_ci break; 3335e5c31af7Sopenharmony_ci } 3336e5c31af7Sopenharmony_ci } 3337e5c31af7Sopenharmony_ci } 3338e5c31af7Sopenharmony_ci } 3339e5c31af7Sopenharmony_ci 3340e5c31af7Sopenharmony_ci if (result) 3341e5c31af7Sopenharmony_ci { 3342e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3343e5c31af7Sopenharmony_ci } 3344e5c31af7Sopenharmony_ci else 3345e5c31af7Sopenharmony_ci { 3346e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3347e5c31af7Sopenharmony_ci } 3348e5c31af7Sopenharmony_ci 3349e5c31af7Sopenharmony_ci return STOP; 3350e5c31af7Sopenharmony_ci} 3351e5c31af7Sopenharmony_ci 3352e5c31af7Sopenharmony_ci/** Constructor 3353e5c31af7Sopenharmony_ci * 3354e5c31af7Sopenharmony_ci * @param context Test context 3355e5c31af7Sopenharmony_ci * @param extParams Not used. 3356e5c31af7Sopenharmony_ci * @param name Test case's name 3357e5c31af7Sopenharmony_ci * @param description Test case's description 3358e5c31af7Sopenharmony_ci **/ 3359e5c31af7Sopenharmony_ciGeometryShaderInsufficientEmittedVerticesTest::GeometryShaderInsufficientEmittedVerticesTest( 3360e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams, const char* name, const char* description) 3361e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 3362e5c31af7Sopenharmony_ci , m_fbo_id(0) 3363e5c31af7Sopenharmony_ci , m_fs_id(0) 3364e5c31af7Sopenharmony_ci , m_gs_ids(NULL) 3365e5c31af7Sopenharmony_ci , m_number_of_color_components(4) 3366e5c31af7Sopenharmony_ci , m_number_of_gs(2 /*taken from test spec*/) 3367e5c31af7Sopenharmony_ci , m_po_ids(NULL) 3368e5c31af7Sopenharmony_ci , m_texture_height(16) 3369e5c31af7Sopenharmony_ci , m_texture_id(0) 3370e5c31af7Sopenharmony_ci , m_texture_width(16) 3371e5c31af7Sopenharmony_ci{ 3372e5c31af7Sopenharmony_ci m_vao_id = 0; 3373e5c31af7Sopenharmony_ci m_vs_id = 0; 3374e5c31af7Sopenharmony_ci 3375e5c31af7Sopenharmony_ci /* Allocate enough memory for glReadPixels() data which is respectively: width, height, RGBA components number. */ 3376e5c31af7Sopenharmony_ci m_pixels = new glw::GLubyte[m_texture_height * m_texture_width * m_number_of_color_components]; 3377e5c31af7Sopenharmony_ci} 3378e5c31af7Sopenharmony_ci 3379e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 3380e5c31af7Sopenharmony_civoid GeometryShaderInsufficientEmittedVerticesTest::deinit() 3381e5c31af7Sopenharmony_ci{ 3382e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3383e5c31af7Sopenharmony_ci 3384e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 3385e5c31af7Sopenharmony_ci 3386e5c31af7Sopenharmony_ci if (m_pixels != NULL) 3387e5c31af7Sopenharmony_ci { 3388e5c31af7Sopenharmony_ci delete[] m_pixels; 3389e5c31af7Sopenharmony_ci m_pixels = NULL; 3390e5c31af7Sopenharmony_ci } 3391e5c31af7Sopenharmony_ci 3392e5c31af7Sopenharmony_ci if (m_fbo_id != 0) 3393e5c31af7Sopenharmony_ci { 3394e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_fbo_id); 3395e5c31af7Sopenharmony_ci m_fbo_id = 0; 3396e5c31af7Sopenharmony_ci } 3397e5c31af7Sopenharmony_ci 3398e5c31af7Sopenharmony_ci if (m_fs_id != 0) 3399e5c31af7Sopenharmony_ci { 3400e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 3401e5c31af7Sopenharmony_ci m_fs_id = 0; 3402e5c31af7Sopenharmony_ci } 3403e5c31af7Sopenharmony_ci 3404e5c31af7Sopenharmony_ci if (m_gs_ids != 0) 3405e5c31af7Sopenharmony_ci { 3406e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3407e5c31af7Sopenharmony_ci { 3408e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_ids[i]); 3409e5c31af7Sopenharmony_ci m_gs_ids[i] = 0; 3410e5c31af7Sopenharmony_ci } 3411e5c31af7Sopenharmony_ci 3412e5c31af7Sopenharmony_ci delete[] m_gs_ids; 3413e5c31af7Sopenharmony_ci m_gs_ids = NULL; 3414e5c31af7Sopenharmony_ci } 3415e5c31af7Sopenharmony_ci 3416e5c31af7Sopenharmony_ci if (m_po_ids != 0) 3417e5c31af7Sopenharmony_ci { 3418e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3419e5c31af7Sopenharmony_ci { 3420e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_ids[i]); 3421e5c31af7Sopenharmony_ci m_po_ids[i] = 0; 3422e5c31af7Sopenharmony_ci } 3423e5c31af7Sopenharmony_ci 3424e5c31af7Sopenharmony_ci delete[] m_po_ids; 3425e5c31af7Sopenharmony_ci m_po_ids = NULL; 3426e5c31af7Sopenharmony_ci } 3427e5c31af7Sopenharmony_ci 3428e5c31af7Sopenharmony_ci if (m_texture_id != 0) 3429e5c31af7Sopenharmony_ci { 3430e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_texture_id); 3431e5c31af7Sopenharmony_ci m_texture_id = 0; 3432e5c31af7Sopenharmony_ci } 3433e5c31af7Sopenharmony_ci 3434e5c31af7Sopenharmony_ci if (m_vao_id != 0) 3435e5c31af7Sopenharmony_ci { 3436e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 3437e5c31af7Sopenharmony_ci m_vao_id = 0; 3438e5c31af7Sopenharmony_ci } 3439e5c31af7Sopenharmony_ci 3440e5c31af7Sopenharmony_ci if (m_vs_id != 0) 3441e5c31af7Sopenharmony_ci { 3442e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 3443e5c31af7Sopenharmony_ci m_vs_id = 0; 3444e5c31af7Sopenharmony_ci } 3445e5c31af7Sopenharmony_ci 3446e5c31af7Sopenharmony_ci /* Release base class */ 3447e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 3448e5c31af7Sopenharmony_ci} 3449e5c31af7Sopenharmony_ci 3450e5c31af7Sopenharmony_ci/** Executes the test. 3451e5c31af7Sopenharmony_ci * 3452e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 3453e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 3454e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 3455e5c31af7Sopenharmony_ci **/ 3456e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderInsufficientEmittedVerticesTest::iterate() 3457e5c31af7Sopenharmony_ci{ 3458e5c31af7Sopenharmony_ci /* Define Fragment Shader for purpose of this test. */ 3459e5c31af7Sopenharmony_ci const char* fs_code = "${VERSION}\n" 3460e5c31af7Sopenharmony_ci "\n" 3461e5c31af7Sopenharmony_ci "precision highp float;\n" 3462e5c31af7Sopenharmony_ci "\n" 3463e5c31af7Sopenharmony_ci "out vec4 result;\n" 3464e5c31af7Sopenharmony_ci "\n" 3465e5c31af7Sopenharmony_ci "void main()\n" 3466e5c31af7Sopenharmony_ci "{\n" 3467e5c31af7Sopenharmony_ci " result = vec4(1.0, 0.0, 0.0, 0.0);\n" 3468e5c31af7Sopenharmony_ci "}\n"; 3469e5c31af7Sopenharmony_ci 3470e5c31af7Sopenharmony_ci /* Define 2 Geometry Shaders for purpose of this test. */ 3471e5c31af7Sopenharmony_ci const char* gs_line_strip = "${VERSION}\n" 3472e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3473e5c31af7Sopenharmony_ci "\n" 3474e5c31af7Sopenharmony_ci "layout (points) in;\n" 3475e5c31af7Sopenharmony_ci "layout (line_strip, max_vertices = 2) out;\n" 3476e5c31af7Sopenharmony_ci "\n" 3477e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3478e5c31af7Sopenharmony_ci "\n" 3479e5c31af7Sopenharmony_ci "void main()\n" 3480e5c31af7Sopenharmony_ci "{\n" 3481e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3482e5c31af7Sopenharmony_ci " gl_Position.zw = vec2(0.0, 1.0);\n" 3483e5c31af7Sopenharmony_ci " EmitVertex();\n" 3484e5c31af7Sopenharmony_ci "}\n"; 3485e5c31af7Sopenharmony_ci 3486e5c31af7Sopenharmony_ci const char* gs_triangle_strip = "${VERSION}\n" 3487e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3488e5c31af7Sopenharmony_ci "\n" 3489e5c31af7Sopenharmony_ci "layout (points) in;\n" 3490e5c31af7Sopenharmony_ci "layout (triangle_strip, max_vertices = 3) out;\n" 3491e5c31af7Sopenharmony_ci "\n" 3492e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}" 3493e5c31af7Sopenharmony_ci "\n" 3494e5c31af7Sopenharmony_ci "void main()\n" 3495e5c31af7Sopenharmony_ci "{\n" 3496e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3497e5c31af7Sopenharmony_ci " gl_Position.zw = vec2(0.0, 1.0);\n" 3498e5c31af7Sopenharmony_ci " EmitVertex();\n" 3499e5c31af7Sopenharmony_ci 3500e5c31af7Sopenharmony_ci " gl_Position = gl_in[0].gl_Position;\n" 3501e5c31af7Sopenharmony_ci " gl_Position.zw = vec2(0.0, 1.0);\n" 3502e5c31af7Sopenharmony_ci " EmitVertex();\n" 3503e5c31af7Sopenharmony_ci "}\n"; 3504e5c31af7Sopenharmony_ci 3505e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 3506e5c31af7Sopenharmony_ci bool result = true; 3507e5c31af7Sopenharmony_ci 3508e5c31af7Sopenharmony_ci m_gs_ids = new glw::GLuint[m_number_of_gs]; 3509e5c31af7Sopenharmony_ci m_po_ids = new glw::GLuint[m_number_of_gs]; 3510e5c31af7Sopenharmony_ci 3511e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 3512e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 3513e5c31af7Sopenharmony_ci { 3514e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 3515e5c31af7Sopenharmony_ci } 3516e5c31af7Sopenharmony_ci 3517e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3518e5c31af7Sopenharmony_ci 3519e5c31af7Sopenharmony_ci /* Create program objects & geometry shader objects. */ 3520e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3521e5c31af7Sopenharmony_ci { 3522e5c31af7Sopenharmony_ci m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER); 3523e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 3524e5c31af7Sopenharmony_ci 3525e5c31af7Sopenharmony_ci m_po_ids[i] = gl.createProgram(); 3526e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 3527e5c31af7Sopenharmony_ci } 3528e5c31af7Sopenharmony_ci 3529e5c31af7Sopenharmony_ci /* Create shader object. */ 3530e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 3531e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 3532e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 3533e5c31af7Sopenharmony_ci 3534e5c31af7Sopenharmony_ci /* Try to link the test program object */ 3535e5c31af7Sopenharmony_ci std::string fs_code_specialized = specializeShader(1, &fs_code); 3536e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = fs_code_specialized.c_str(); 3537e5c31af7Sopenharmony_ci 3538e5c31af7Sopenharmony_ci std::string gs_codes_specialized[] = { specializeShader(1, &gs_line_strip), 3539e5c31af7Sopenharmony_ci specializeShader(1, &gs_triangle_strip) }; 3540e5c31af7Sopenharmony_ci 3541e5c31af7Sopenharmony_ci const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str() }; 3542e5c31af7Sopenharmony_ci 3543e5c31af7Sopenharmony_ci std::string vs_code_specialized = specializeShader(1, &minimal_vs_code); 3544e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = vs_code_specialized.c_str(); 3545e5c31af7Sopenharmony_ci 3546e5c31af7Sopenharmony_ci for (glw::GLuint i = 0; i < m_number_of_gs; ++i) 3547e5c31af7Sopenharmony_ci { 3548e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */ 3549e5c31af7Sopenharmony_ci &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */ 3550e5c31af7Sopenharmony_ci &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */ 3551e5c31af7Sopenharmony_ci &vs_code_specialized_raw, &has_shader_compilation_failed)) 3552e5c31af7Sopenharmony_ci { 3553e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = " 3554e5c31af7Sopenharmony_ci << "[" << i << "]." << tcu::TestLog::EndMessage; 3555e5c31af7Sopenharmony_ci 3556e5c31af7Sopenharmony_ci result = false; 3557e5c31af7Sopenharmony_ci break; 3558e5c31af7Sopenharmony_ci } 3559e5c31af7Sopenharmony_ci } 3560e5c31af7Sopenharmony_ci 3561e5c31af7Sopenharmony_ci if (result) 3562e5c31af7Sopenharmony_ci { 3563e5c31af7Sopenharmony_ci /* Create a 2D texture. */ 3564e5c31af7Sopenharmony_ci gl.genTextures(1, &m_texture_id); 3565e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed."); 3566e5c31af7Sopenharmony_ci 3567e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, m_texture_id); 3568e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed."); 3569e5c31af7Sopenharmony_ci 3570e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_RGBA8, 16 /*width taken from spec*/, 3571e5c31af7Sopenharmony_ci 16 /*height taken from spec*/); 3572e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed."); 3573e5c31af7Sopenharmony_ci 3574e5c31af7Sopenharmony_ci /* Configure FBO. */ 3575e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_fbo_id); 3576e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed."); 3577e5c31af7Sopenharmony_ci 3578e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id); 3579e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed."); 3580e5c31af7Sopenharmony_ci 3581e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /*level*/); 3582e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed."); 3583e5c31af7Sopenharmony_ci 3584e5c31af7Sopenharmony_ci /* Configure VAO. */ 3585e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 3586e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed."); 3587e5c31af7Sopenharmony_ci 3588e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 3589e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed."); 3590e5c31af7Sopenharmony_ci 3591e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 1.0f, 0.0f, 0.0f); 3592e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed."); 3593e5c31af7Sopenharmony_ci 3594e5c31af7Sopenharmony_ci for (glw::GLuint po = 0; po < m_number_of_gs; ++po) 3595e5c31af7Sopenharmony_ci { 3596e5c31af7Sopenharmony_ci /* Use Program Object. */ 3597e5c31af7Sopenharmony_ci gl.useProgram(m_po_ids[po]); 3598e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed."); 3599e5c31af7Sopenharmony_ci 3600e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 3601e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed."); 3602e5c31af7Sopenharmony_ci 3603e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/); 3604e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname."); 3605e5c31af7Sopenharmony_ci 3606e5c31af7Sopenharmony_ci gl.readPixels(0 /*x*/, 0 /*y*/, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels); 3607e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed."); 3608e5c31af7Sopenharmony_ci 3609e5c31af7Sopenharmony_ci for (glw::GLuint pixel = 0; pixel < (m_texture_width * m_texture_height * m_number_of_color_components - 3610e5c31af7Sopenharmony_ci m_number_of_color_components); 3611e5c31af7Sopenharmony_ci pixel += m_number_of_color_components) 3612e5c31af7Sopenharmony_ci { 3613e5c31af7Sopenharmony_ci if (m_pixels[pixel] != 0 && m_pixels[pixel + 1] != 255 && m_pixels[pixel + 2] != 0 && 3614e5c31af7Sopenharmony_ci m_pixels[pixel + 3] != 0) 3615e5c31af7Sopenharmony_ci { 3616e5c31af7Sopenharmony_ci result = false; 3617e5c31af7Sopenharmony_ci 3618e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Pixel [" << pixel << "] has color = [" 3619e5c31af7Sopenharmony_ci << m_pixels[pixel] << ", " << m_pixels[pixel + 1] << ", " << m_pixels[pixel + 2] 3620e5c31af7Sopenharmony_ci << ", " << m_pixels[pixel + 3] << "] " 3621e5c31af7Sopenharmony_ci << "instead of [0, 255, 0, 0]." << tcu::TestLog::EndMessage; 3622e5c31af7Sopenharmony_ci 3623e5c31af7Sopenharmony_ci break; 3624e5c31af7Sopenharmony_ci } 3625e5c31af7Sopenharmony_ci } 3626e5c31af7Sopenharmony_ci } 3627e5c31af7Sopenharmony_ci } 3628e5c31af7Sopenharmony_ci 3629e5c31af7Sopenharmony_ci if (result) 3630e5c31af7Sopenharmony_ci { 3631e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3632e5c31af7Sopenharmony_ci } 3633e5c31af7Sopenharmony_ci else 3634e5c31af7Sopenharmony_ci { 3635e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3636e5c31af7Sopenharmony_ci } 3637e5c31af7Sopenharmony_ci 3638e5c31af7Sopenharmony_ci return STOP; 3639e5c31af7Sopenharmony_ci} 3640e5c31af7Sopenharmony_ci 3641e5c31af7Sopenharmony_ci/** Constructor 3642e5c31af7Sopenharmony_ci * 3643e5c31af7Sopenharmony_ci * @param context Test context 3644e5c31af7Sopenharmony_ci * @param extParams Not used. 3645e5c31af7Sopenharmony_ci * @param name Test case's name 3646e5c31af7Sopenharmony_ci * @param description Test case's description 3647e5c31af7Sopenharmony_ci **/ 3648e5c31af7Sopenharmony_ciGeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest:: 3649e5c31af7Sopenharmony_ci GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest(Context& context, 3650e5c31af7Sopenharmony_ci const ExtParameters& extParams, 3651e5c31af7Sopenharmony_ci const char* name, 3652e5c31af7Sopenharmony_ci const char* description) 3653e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description) 3654e5c31af7Sopenharmony_ci , m_gs_id(0) 3655e5c31af7Sopenharmony_ci , m_gs_po_id(0) 3656e5c31af7Sopenharmony_ci , m_ppo_id(0) 3657e5c31af7Sopenharmony_ci , m_tfbo_id(0) 3658e5c31af7Sopenharmony_ci , m_vao_id(0) 3659e5c31af7Sopenharmony_ci , m_vs_id(0) 3660e5c31af7Sopenharmony_ci , m_vs_po_id(0) 3661e5c31af7Sopenharmony_ci{ 3662e5c31af7Sopenharmony_ci} 3663e5c31af7Sopenharmony_ci 3664e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 3665e5c31af7Sopenharmony_civoid GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::deinit() 3666e5c31af7Sopenharmony_ci{ 3667e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3668e5c31af7Sopenharmony_ci 3669e5c31af7Sopenharmony_ci if (m_gs_id != 0) 3670e5c31af7Sopenharmony_ci { 3671e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 3672e5c31af7Sopenharmony_ci m_gs_id = 0; 3673e5c31af7Sopenharmony_ci } 3674e5c31af7Sopenharmony_ci 3675e5c31af7Sopenharmony_ci if (m_gs_po_id != 0) 3676e5c31af7Sopenharmony_ci { 3677e5c31af7Sopenharmony_ci gl.deleteProgram(m_gs_po_id); 3678e5c31af7Sopenharmony_ci m_gs_po_id = 0; 3679e5c31af7Sopenharmony_ci } 3680e5c31af7Sopenharmony_ci 3681e5c31af7Sopenharmony_ci if (m_ppo_id != 0) 3682e5c31af7Sopenharmony_ci { 3683e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &m_ppo_id); 3684e5c31af7Sopenharmony_ci m_ppo_id = 0; 3685e5c31af7Sopenharmony_ci } 3686e5c31af7Sopenharmony_ci 3687e5c31af7Sopenharmony_ci if (m_tfbo_id != 0) 3688e5c31af7Sopenharmony_ci { 3689e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_tfbo_id); 3690e5c31af7Sopenharmony_ci m_tfbo_id = 0; 3691e5c31af7Sopenharmony_ci } 3692e5c31af7Sopenharmony_ci 3693e5c31af7Sopenharmony_ci if (m_vao_id != 0) 3694e5c31af7Sopenharmony_ci { 3695e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 3696e5c31af7Sopenharmony_ci m_vao_id = 0; 3697e5c31af7Sopenharmony_ci } 3698e5c31af7Sopenharmony_ci 3699e5c31af7Sopenharmony_ci if (m_vs_id != 0) 3700e5c31af7Sopenharmony_ci { 3701e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 3702e5c31af7Sopenharmony_ci m_vs_id = 0; 3703e5c31af7Sopenharmony_ci } 3704e5c31af7Sopenharmony_ci 3705e5c31af7Sopenharmony_ci if (m_vs_po_id != 0) 3706e5c31af7Sopenharmony_ci { 3707e5c31af7Sopenharmony_ci gl.deleteProgram(m_vs_po_id); 3708e5c31af7Sopenharmony_ci m_vs_po_id = 0; 3709e5c31af7Sopenharmony_ci } 3710e5c31af7Sopenharmony_ci 3711e5c31af7Sopenharmony_ci /* Release base class */ 3712e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 3713e5c31af7Sopenharmony_ci} 3714e5c31af7Sopenharmony_ci 3715e5c31af7Sopenharmony_ci/** Executes the test. 3716e5c31af7Sopenharmony_ci * 3717e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 3718e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 3719e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 3720e5c31af7Sopenharmony_ci **/ 3721e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::iterate() 3722e5c31af7Sopenharmony_ci{ 3723e5c31af7Sopenharmony_ci /* Define Geometry Shader for purpose of this test. */ 3724e5c31af7Sopenharmony_ci const char* gs_code = 3725e5c31af7Sopenharmony_ci "${VERSION}\n" 3726e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 3727e5c31af7Sopenharmony_ci "${IN_PER_VERTEX_DECL_ARRAY}\n" 3728e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}\n" 3729e5c31af7Sopenharmony_ci "\n" 3730e5c31af7Sopenharmony_ci "layout (points) in;\n" 3731e5c31af7Sopenharmony_ci "layout (points, max_vertices = 1) out;\n" 3732e5c31af7Sopenharmony_ci "\n" 3733e5c31af7Sopenharmony_ci "flat in int vertexID[];\n" 3734e5c31af7Sopenharmony_ci "flat in ivec4 out_vs_1[];\n" 3735e5c31af7Sopenharmony_ci "\n" 3736e5c31af7Sopenharmony_ci "out vec4 out_gs_1;\n" 3737e5c31af7Sopenharmony_ci "\n" 3738e5c31af7Sopenharmony_ci "void main()\n" 3739e5c31af7Sopenharmony_ci "{\n" 3740e5c31af7Sopenharmony_ci " out_gs_1 = vec4(vertexID[0] * 2, vertexID[0] * 2 + 1, vertexID[0] * 2 + 2, vertexID[0] * 2 + 3);\n" 3741e5c31af7Sopenharmony_ci " gl_Position = vec4(0, 0, 0, 1);\n" 3742e5c31af7Sopenharmony_ci " EmitVertex();\n" 3743e5c31af7Sopenharmony_ci "}\n"; 3744e5c31af7Sopenharmony_ci 3745e5c31af7Sopenharmony_ci /* Define Vertex Shader for purpose of this test. */ 3746e5c31af7Sopenharmony_ci const char* vs_code = "${VERSION}\n" 3747e5c31af7Sopenharmony_ci "${OUT_PER_VERTEX_DECL}\n" 3748e5c31af7Sopenharmony_ci "\n" 3749e5c31af7Sopenharmony_ci "flat out ivec4 out_vs_1;\n" 3750e5c31af7Sopenharmony_ci "flat out int vertexID;\n" 3751e5c31af7Sopenharmony_ci "\n" 3752e5c31af7Sopenharmony_ci "void main()\n" 3753e5c31af7Sopenharmony_ci "{\n" 3754e5c31af7Sopenharmony_ci " vertexID = gl_VertexID;\n" 3755e5c31af7Sopenharmony_ci " out_vs_1 = ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);\n" 3756e5c31af7Sopenharmony_ci " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n" 3757e5c31af7Sopenharmony_ci "}\n"; 3758e5c31af7Sopenharmony_ci 3759e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 3760e5c31af7Sopenharmony_ci bool result = true; 3761e5c31af7Sopenharmony_ci glw::GLfloat* ptrTF_data_f = NULL; 3762e5c31af7Sopenharmony_ci glw::GLuint* ptrTF_data_ui = NULL; 3763e5c31af7Sopenharmony_ci glw::GLfloat expected_geom_results[] = { 0.0f, 1.0f, 2.0f, 3.0f }; 3764e5c31af7Sopenharmony_ci glw::GLuint expected_vertex_results[] = { 0, 1, 2, 3 }; 3765e5c31af7Sopenharmony_ci glw::GLfloat epsilon = 1e-5f; 3766e5c31af7Sopenharmony_ci 3767e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 3768e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 3769e5c31af7Sopenharmony_ci { 3770e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 3771e5c31af7Sopenharmony_ci } 3772e5c31af7Sopenharmony_ci 3773e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3774e5c31af7Sopenharmony_ci 3775e5c31af7Sopenharmony_ci /* Create separable program objects. */ 3776e5c31af7Sopenharmony_ci m_gs_po_id = gl.createProgram(); 3777e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 3778e5c31af7Sopenharmony_ci 3779e5c31af7Sopenharmony_ci gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 3780e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed."); 3781e5c31af7Sopenharmony_ci 3782e5c31af7Sopenharmony_ci m_vs_po_id = gl.createProgram(); 3783e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 3784e5c31af7Sopenharmony_ci 3785e5c31af7Sopenharmony_ci gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE); 3786e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed."); 3787e5c31af7Sopenharmony_ci 3788e5c31af7Sopenharmony_ci /* Create shader objects. */ 3789e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 3790e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 3791e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 3792e5c31af7Sopenharmony_ci 3793e5c31af7Sopenharmony_ci /* Try to link the test program object */ 3794e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, &gs_code); 3795e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = gs_code_specialized.c_str(); 3796e5c31af7Sopenharmony_ci 3797e5c31af7Sopenharmony_ci std::string vs_code_specialized = specializeShader(1, &vs_code); 3798e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = vs_code_specialized.c_str(); 3799e5c31af7Sopenharmony_ci 3800e5c31af7Sopenharmony_ci /* Specify output variables to be captured. */ 3801e5c31af7Sopenharmony_ci const char* tf_varyings[2] = { "out_gs_1", "out_vs_1" }; 3802e5c31af7Sopenharmony_ci 3803e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_gs_po_id, 1 /*count*/, &tf_varyings[0], GL_INTERLEAVED_ATTRIBS); 3804e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed."); 3805e5c31af7Sopenharmony_ci 3806e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_vs_po_id, 1 /*count*/, &tf_varyings[1], GL_INTERLEAVED_ATTRIBS); 3807e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed."); 3808e5c31af7Sopenharmony_ci 3809e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */ 3810e5c31af7Sopenharmony_ci &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */ 3811e5c31af7Sopenharmony_ci NULL, 0, 0, /* n_sh3_body_parts */ 3812e5c31af7Sopenharmony_ci NULL, &has_shader_compilation_failed)) 3813e5c31af7Sopenharmony_ci { 3814e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed." 3815e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3816e5c31af7Sopenharmony_ci 3817e5c31af7Sopenharmony_ci result = false; 3818e5c31af7Sopenharmony_ci goto end; 3819e5c31af7Sopenharmony_ci } 3820e5c31af7Sopenharmony_ci 3821e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_vs_po_id, m_vs_id, 1, /* n_sh1_body_parts */ 3822e5c31af7Sopenharmony_ci &vs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */ 3823e5c31af7Sopenharmony_ci NULL, 0, 0, /* n_sh3_body_parts */ 3824e5c31af7Sopenharmony_ci NULL, &has_shader_compilation_failed)) 3825e5c31af7Sopenharmony_ci { 3826e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed." 3827e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3828e5c31af7Sopenharmony_ci 3829e5c31af7Sopenharmony_ci result = false; 3830e5c31af7Sopenharmony_ci goto end; 3831e5c31af7Sopenharmony_ci } 3832e5c31af7Sopenharmony_ci 3833e5c31af7Sopenharmony_ci /* Create and configure Program Pipeline Object. */ 3834e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &m_ppo_id); 3835e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call(s) failed."); 3836e5c31af7Sopenharmony_ci 3837e5c31af7Sopenharmony_ci gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id); 3838e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed."); 3839e5c31af7Sopenharmony_ci 3840e5c31af7Sopenharmony_ci gl.useProgramStages(m_ppo_id, GL_VERTEX_SHADER_BIT, m_vs_po_id); 3841e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed."); 3842e5c31af7Sopenharmony_ci 3843e5c31af7Sopenharmony_ci /* Create Vertex Array Object. */ 3844e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 3845e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed."); 3846e5c31af7Sopenharmony_ci 3847e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 3848e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed."); 3849e5c31af7Sopenharmony_ci 3850e5c31af7Sopenharmony_ci /* Create Buffer Object for Transform Feedback data. */ 3851e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_tfbo_id); 3852e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed."); 3853e5c31af7Sopenharmony_ci 3854e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id); 3855e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed."); 3856e5c31af7Sopenharmony_ci 3857e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4, NULL, GL_STREAM_READ); 3858e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed."); 3859e5c31af7Sopenharmony_ci 3860e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id); 3861e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed."); 3862e5c31af7Sopenharmony_ci 3863e5c31af7Sopenharmony_ci /* Ensure that there is no program object already bound and bind program pipeline. */ 3864e5c31af7Sopenharmony_ci gl.useProgram(0); 3865e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed."); 3866e5c31af7Sopenharmony_ci 3867e5c31af7Sopenharmony_ci gl.bindProgramPipeline(m_ppo_id); 3868e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call(s) failed."); 3869e5c31af7Sopenharmony_ci 3870e5c31af7Sopenharmony_ci gl.enable(GL_RASTERIZER_DISCARD); 3871e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed."); 3872e5c31af7Sopenharmony_ci 3873e5c31af7Sopenharmony_ci /* First pass - Vertex and Geometry Shaders On. */ 3874e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 3875e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed."); 3876e5c31af7Sopenharmony_ci 3877e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/); 3878e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed."); 3879e5c31af7Sopenharmony_ci 3880e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 3881e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed."); 3882e5c31af7Sopenharmony_ci 3883e5c31af7Sopenharmony_ci /* Retrieve data and check if it is correct. */ 3884e5c31af7Sopenharmony_ci ptrTF_data_f = 3885e5c31af7Sopenharmony_ci (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/, 3886e5c31af7Sopenharmony_ci sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT); 3887e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 3888e5c31af7Sopenharmony_ci 3889e5c31af7Sopenharmony_ci for (size_t i = 0; i < 4; ++i) 3890e5c31af7Sopenharmony_ci { 3891e5c31af7Sopenharmony_ci if (fabs(ptrTF_data_f[i] - expected_geom_results[i]) >= epsilon) 3892e5c31af7Sopenharmony_ci { 3893e5c31af7Sopenharmony_ci result = false; 3894e5c31af7Sopenharmony_ci break; 3895e5c31af7Sopenharmony_ci } 3896e5c31af7Sopenharmony_ci } 3897e5c31af7Sopenharmony_ci 3898e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 3899e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 3900e5c31af7Sopenharmony_ci 3901e5c31af7Sopenharmony_ci ptrTF_data_f = NULL; 3902e5c31af7Sopenharmony_ci 3903e5c31af7Sopenharmony_ci if (!result) 3904e5c31af7Sopenharmony_ci { 3905e5c31af7Sopenharmony_ci goto end; 3906e5c31af7Sopenharmony_ci } 3907e5c31af7Sopenharmony_ci 3908e5c31af7Sopenharmony_ci /* Deactivate Geometry Shader Program Object from Program Pipeline Object. */ 3909e5c31af7Sopenharmony_ci gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, 0 /* program */); 3910e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed."); 3911e5c31af7Sopenharmony_ci 3912e5c31af7Sopenharmony_ci /* Second pass - only Vertex Shader Program On. */ 3913e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_POINTS); 3914e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed."); 3915e5c31af7Sopenharmony_ci 3916e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/); 3917e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed."); 3918e5c31af7Sopenharmony_ci 3919e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 3920e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed."); 3921e5c31af7Sopenharmony_ci 3922e5c31af7Sopenharmony_ci gl.disable(GL_RASTERIZER_DISCARD); 3923e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed."); 3924e5c31af7Sopenharmony_ci 3925e5c31af7Sopenharmony_ci /* Retrieve data and check if it is correct. */ 3926e5c31af7Sopenharmony_ci ptrTF_data_ui = 3927e5c31af7Sopenharmony_ci (glw::GLuint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/, 3928e5c31af7Sopenharmony_ci sizeof(glw::GLuint) * 4 /* four float vector components */, GL_MAP_READ_BIT); 3929e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed."); 3930e5c31af7Sopenharmony_ci 3931e5c31af7Sopenharmony_ci for (size_t i = 0; i < 4; ++i) 3932e5c31af7Sopenharmony_ci { 3933e5c31af7Sopenharmony_ci if (ptrTF_data_ui[i] != expected_vertex_results[i]) 3934e5c31af7Sopenharmony_ci { 3935e5c31af7Sopenharmony_ci result = false; 3936e5c31af7Sopenharmony_ci break; 3937e5c31af7Sopenharmony_ci } 3938e5c31af7Sopenharmony_ci } 3939e5c31af7Sopenharmony_ci 3940e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); 3941e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed."); 3942e5c31af7Sopenharmony_ci 3943e5c31af7Sopenharmony_ci ptrTF_data_ui = NULL; 3944e5c31af7Sopenharmony_ci 3945e5c31af7Sopenharmony_ciend: 3946e5c31af7Sopenharmony_ci if (result) 3947e5c31af7Sopenharmony_ci { 3948e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3949e5c31af7Sopenharmony_ci } 3950e5c31af7Sopenharmony_ci else 3951e5c31af7Sopenharmony_ci { 3952e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3953e5c31af7Sopenharmony_ci } 3954e5c31af7Sopenharmony_ci 3955e5c31af7Sopenharmony_ci return STOP; 3956e5c31af7Sopenharmony_ci} 3957e5c31af7Sopenharmony_ci 3958e5c31af7Sopenharmony_ci/** Constructor 3959e5c31af7Sopenharmony_ci * 3960e5c31af7Sopenharmony_ci * @param context Test context 3961e5c31af7Sopenharmony_ci * @param extParams Not used. 3962e5c31af7Sopenharmony_ci * @param name Test case's name 3963e5c31af7Sopenharmony_ci * @param description Test case's description 3964e5c31af7Sopenharmony_ci **/ 3965e5c31af7Sopenharmony_ciGeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives( 3966e5c31af7Sopenharmony_ci Context& context, const ExtParameters& extParams, const char* name, const char* description) 3967e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_tfbo_id(0) 3968e5c31af7Sopenharmony_ci{ 3969e5c31af7Sopenharmony_ci m_vao_id = 0; 3970e5c31af7Sopenharmony_ci m_vs_id = 0; 3971e5c31af7Sopenharmony_ci} 3972e5c31af7Sopenharmony_ci 3973e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 3974e5c31af7Sopenharmony_civoid GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::deinit() 3975e5c31af7Sopenharmony_ci{ 3976e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3977e5c31af7Sopenharmony_ci 3978e5c31af7Sopenharmony_ci if (m_fs_id != 0) 3979e5c31af7Sopenharmony_ci { 3980e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 3981e5c31af7Sopenharmony_ci m_fs_id = 0; 3982e5c31af7Sopenharmony_ci } 3983e5c31af7Sopenharmony_ci 3984e5c31af7Sopenharmony_ci if (m_gs_id != 0) 3985e5c31af7Sopenharmony_ci { 3986e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 3987e5c31af7Sopenharmony_ci m_gs_id = 0; 3988e5c31af7Sopenharmony_ci } 3989e5c31af7Sopenharmony_ci 3990e5c31af7Sopenharmony_ci if (m_po_id != 0) 3991e5c31af7Sopenharmony_ci { 3992e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_id); 3993e5c31af7Sopenharmony_ci m_po_id = 0; 3994e5c31af7Sopenharmony_ci } 3995e5c31af7Sopenharmony_ci 3996e5c31af7Sopenharmony_ci if (m_tfbo_id != 0) 3997e5c31af7Sopenharmony_ci { 3998e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_tfbo_id); 3999e5c31af7Sopenharmony_ci m_tfbo_id = 0; 4000e5c31af7Sopenharmony_ci } 4001e5c31af7Sopenharmony_ci 4002e5c31af7Sopenharmony_ci if (m_vao_id != 0) 4003e5c31af7Sopenharmony_ci { 4004e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 4005e5c31af7Sopenharmony_ci m_vao_id = 0; 4006e5c31af7Sopenharmony_ci } 4007e5c31af7Sopenharmony_ci 4008e5c31af7Sopenharmony_ci if (m_vs_id != 0) 4009e5c31af7Sopenharmony_ci { 4010e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 4011e5c31af7Sopenharmony_ci m_vs_id = 0; 4012e5c31af7Sopenharmony_ci } 4013e5c31af7Sopenharmony_ci 4014e5c31af7Sopenharmony_ci /* Release base class */ 4015e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 4016e5c31af7Sopenharmony_ci} 4017e5c31af7Sopenharmony_ci 4018e5c31af7Sopenharmony_ci/** Executes the test. 4019e5c31af7Sopenharmony_ci * 4020e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 4021e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 4022e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 4023e5c31af7Sopenharmony_ci **/ 4024e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::iterate() 4025e5c31af7Sopenharmony_ci{ 4026e5c31af7Sopenharmony_ci /* Define Geometry Shader for purpose of this test. */ 4027e5c31af7Sopenharmony_ci const char* gs_code = "${VERSION}\n" 4028e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 4029e5c31af7Sopenharmony_ci "\n" 4030e5c31af7Sopenharmony_ci "layout (lines) in;\n" 4031e5c31af7Sopenharmony_ci "layout (triangle_strip, max_vertices = 3) out;\n" 4032e5c31af7Sopenharmony_ci "\n" 4033e5c31af7Sopenharmony_ci "out vec4 out_gs_1;\n" 4034e5c31af7Sopenharmony_ci "\n" 4035e5c31af7Sopenharmony_ci "void main()\n" 4036e5c31af7Sopenharmony_ci "{\n" 4037e5c31af7Sopenharmony_ci " out_gs_1 = vec4(4.0, 3.0, 2.0, 1.0);\n" 4038e5c31af7Sopenharmony_ci "\n" 4039e5c31af7Sopenharmony_ci " gl_Position = vec4(0, 0, 0, 1);\n" 4040e5c31af7Sopenharmony_ci " EmitVertex();\n" 4041e5c31af7Sopenharmony_ci "\n" 4042e5c31af7Sopenharmony_ci " gl_Position = vec4(1, 0, 0, 1);\n" 4043e5c31af7Sopenharmony_ci " EmitVertex();\n" 4044e5c31af7Sopenharmony_ci "\n" 4045e5c31af7Sopenharmony_ci " gl_Position = vec4(1, 1, 0, 1);\n" 4046e5c31af7Sopenharmony_ci " EmitVertex();\n" 4047e5c31af7Sopenharmony_ci "\n" 4048e5c31af7Sopenharmony_ci " EndPrimitive();" 4049e5c31af7Sopenharmony_ci "}\n"; 4050e5c31af7Sopenharmony_ci 4051e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 4052e5c31af7Sopenharmony_ci bool result = true; 4053e5c31af7Sopenharmony_ci glw::GLenum error = GL_NO_ERROR; 4054e5c31af7Sopenharmony_ci 4055e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 4056e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 4057e5c31af7Sopenharmony_ci { 4058e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 4059e5c31af7Sopenharmony_ci } 4060e5c31af7Sopenharmony_ci 4061e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4062e5c31af7Sopenharmony_ci 4063e5c31af7Sopenharmony_ci /* Create program object. */ 4064e5c31af7Sopenharmony_ci m_po_id = gl.createProgram(); 4065e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed."); 4066e5c31af7Sopenharmony_ci 4067e5c31af7Sopenharmony_ci /* Specify output variables to be captured. */ 4068e5c31af7Sopenharmony_ci const char* tf_varyings[] = { "out_gs_1" }; 4069e5c31af7Sopenharmony_ci 4070e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_po_id, 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS); 4071e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed."); 4072e5c31af7Sopenharmony_ci 4073e5c31af7Sopenharmony_ci /* Create shader objects. */ 4074e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 4075e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 4076e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 4077e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 4078e5c31af7Sopenharmony_ci 4079e5c31af7Sopenharmony_ci /* Try to link the test program object */ 4080e5c31af7Sopenharmony_ci std::string fs_code_specialized = specializeShader(1, &minimal_fs_code); 4081e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = fs_code_specialized.c_str(); 4082e5c31af7Sopenharmony_ci 4083e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, &gs_code); 4084e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = gs_code_specialized.c_str(); 4085e5c31af7Sopenharmony_ci 4086e5c31af7Sopenharmony_ci std::string vs_code_specialized = specializeShader(1, &minimal_vs_code); 4087e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = vs_code_specialized.c_str(); 4088e5c31af7Sopenharmony_ci 4089e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_id, m_fs_id, 1, /* n_sh1_body_parts */ 4090e5c31af7Sopenharmony_ci &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */ 4091e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */ 4092e5c31af7Sopenharmony_ci &vs_code_specialized_raw, &has_shader_compilation_failed)) 4093e5c31af7Sopenharmony_ci { 4094e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed whereas a success was expected." 4095e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 4096e5c31af7Sopenharmony_ci 4097e5c31af7Sopenharmony_ci result = false; 4098e5c31af7Sopenharmony_ci goto end; 4099e5c31af7Sopenharmony_ci } 4100e5c31af7Sopenharmony_ci 4101e5c31af7Sopenharmony_ci /* Create Vertex Array Object. */ 4102e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 4103e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed."); 4104e5c31af7Sopenharmony_ci 4105e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 4106e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed."); 4107e5c31af7Sopenharmony_ci 4108e5c31af7Sopenharmony_ci /* Create Buffer Object for Transform Feedback data. */ 4109e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_tfbo_id); 4110e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed."); 4111e5c31af7Sopenharmony_ci 4112e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id); 4113e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed."); 4114e5c31af7Sopenharmony_ci 4115e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, 4116e5c31af7Sopenharmony_ci sizeof(glw::GLfloat) * 4 * 3 /* capture 4 float vector components times 3 triangle vertices */, NULL, 4117e5c31af7Sopenharmony_ci GL_STREAM_READ); 4118e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed."); 4119e5c31af7Sopenharmony_ci 4120e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id); 4121e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed."); 4122e5c31af7Sopenharmony_ci 4123e5c31af7Sopenharmony_ci /* Turn on program object. */ 4124e5c31af7Sopenharmony_ci gl.useProgram(m_po_id); 4125e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed."); 4126e5c31af7Sopenharmony_ci 4127e5c31af7Sopenharmony_ci gl.enable(GL_RASTERIZER_DISCARD); 4128e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed."); 4129e5c31af7Sopenharmony_ci 4130e5c31af7Sopenharmony_ci gl.beginTransformFeedback(GL_LINES); 4131e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed."); 4132e5c31af7Sopenharmony_ci 4133e5c31af7Sopenharmony_ci gl.drawArrays(GL_TRIANGLES, 0 /*first*/, 3 /*count*/); 4134e5c31af7Sopenharmony_ci 4135e5c31af7Sopenharmony_ci error = gl.getError(); 4136e5c31af7Sopenharmony_ci 4137e5c31af7Sopenharmony_ci if (error != GL_INVALID_OPERATION) 4138e5c31af7Sopenharmony_ci { 4139e5c31af7Sopenharmony_ci result = false; 4140e5c31af7Sopenharmony_ci 4141e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated." 4142e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 4143e5c31af7Sopenharmony_ci } 4144e5c31af7Sopenharmony_ci 4145e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 4146e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed."); 4147e5c31af7Sopenharmony_ci 4148e5c31af7Sopenharmony_ci gl.disable(GL_RASTERIZER_DISCARD); 4149e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed."); 4150e5c31af7Sopenharmony_ci 4151e5c31af7Sopenharmony_ciend: 4152e5c31af7Sopenharmony_ci 4153e5c31af7Sopenharmony_ci if (result) 4154e5c31af7Sopenharmony_ci { 4155e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4156e5c31af7Sopenharmony_ci } 4157e5c31af7Sopenharmony_ci else 4158e5c31af7Sopenharmony_ci { 4159e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4160e5c31af7Sopenharmony_ci } 4161e5c31af7Sopenharmony_ci 4162e5c31af7Sopenharmony_ci return STOP; 4163e5c31af7Sopenharmony_ci} 4164e5c31af7Sopenharmony_ci 4165e5c31af7Sopenharmony_ci/** Constructor 4166e5c31af7Sopenharmony_ci * 4167e5c31af7Sopenharmony_ci * @param context Test context 4168e5c31af7Sopenharmony_ci * @param extParams Not used. 4169e5c31af7Sopenharmony_ci * @param name Test case's name 4170e5c31af7Sopenharmony_ci * @param description Test case's description 4171e5c31af7Sopenharmony_ci **/ 4172e5c31af7Sopenharmony_ciGeometryShaderDrawCallsWhileTFPaused::GeometryShaderDrawCallsWhileTFPaused(Context& context, 4173e5c31af7Sopenharmony_ci const ExtParameters& extParams, 4174e5c31af7Sopenharmony_ci const char* name, const char* description) 4175e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_tfbo_id(0) 4176e5c31af7Sopenharmony_ci{ 4177e5c31af7Sopenharmony_ci m_vao_id = 0; 4178e5c31af7Sopenharmony_ci m_vs_id = 0; 4179e5c31af7Sopenharmony_ci} 4180e5c31af7Sopenharmony_ci 4181e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. */ 4182e5c31af7Sopenharmony_civoid GeometryShaderDrawCallsWhileTFPaused::deinit() 4183e5c31af7Sopenharmony_ci{ 4184e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4185e5c31af7Sopenharmony_ci 4186e5c31af7Sopenharmony_ci if (m_fs_id != 0) 4187e5c31af7Sopenharmony_ci { 4188e5c31af7Sopenharmony_ci gl.deleteShader(m_fs_id); 4189e5c31af7Sopenharmony_ci m_fs_id = 0; 4190e5c31af7Sopenharmony_ci } 4191e5c31af7Sopenharmony_ci 4192e5c31af7Sopenharmony_ci if (m_gs_id != 0) 4193e5c31af7Sopenharmony_ci { 4194e5c31af7Sopenharmony_ci gl.deleteShader(m_gs_id); 4195e5c31af7Sopenharmony_ci m_gs_id = 0; 4196e5c31af7Sopenharmony_ci } 4197e5c31af7Sopenharmony_ci 4198e5c31af7Sopenharmony_ci for (int i = 0; i < 15 /* All combinations of possible inputs and outputs in GS */; ++i) 4199e5c31af7Sopenharmony_ci { 4200e5c31af7Sopenharmony_ci if (m_po_ids[i] != 0) 4201e5c31af7Sopenharmony_ci { 4202e5c31af7Sopenharmony_ci gl.deleteProgram(m_po_ids[i]); 4203e5c31af7Sopenharmony_ci m_po_ids[i] = 0; 4204e5c31af7Sopenharmony_ci } 4205e5c31af7Sopenharmony_ci } 4206e5c31af7Sopenharmony_ci 4207e5c31af7Sopenharmony_ci if (m_tfbo_id != 0) 4208e5c31af7Sopenharmony_ci { 4209e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_tfbo_id); 4210e5c31af7Sopenharmony_ci m_tfbo_id = 0; 4211e5c31af7Sopenharmony_ci } 4212e5c31af7Sopenharmony_ci 4213e5c31af7Sopenharmony_ci if (m_vao_id != 0) 4214e5c31af7Sopenharmony_ci { 4215e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 4216e5c31af7Sopenharmony_ci m_vao_id = 0; 4217e5c31af7Sopenharmony_ci } 4218e5c31af7Sopenharmony_ci 4219e5c31af7Sopenharmony_ci if (m_vs_id != 0) 4220e5c31af7Sopenharmony_ci { 4221e5c31af7Sopenharmony_ci gl.deleteShader(m_vs_id); 4222e5c31af7Sopenharmony_ci m_vs_id = 0; 4223e5c31af7Sopenharmony_ci } 4224e5c31af7Sopenharmony_ci 4225e5c31af7Sopenharmony_ci /* Release base class */ 4226e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 4227e5c31af7Sopenharmony_ci} 4228e5c31af7Sopenharmony_ci 4229e5c31af7Sopenharmony_ci/** Executes the test. 4230e5c31af7Sopenharmony_ci * 4231e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 4232e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 4233e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 4234e5c31af7Sopenharmony_ci **/ 4235e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderDrawCallsWhileTFPaused::iterate() 4236e5c31af7Sopenharmony_ci{ 4237e5c31af7Sopenharmony_ci /* Define 15 (all combinations of possible inputs and outputs in geometry shader) Geometry Shaders for purpose of this test. */ 4238e5c31af7Sopenharmony_ci const std::string gs_inputs[] = { "points", "lines", "lines_adjacency", "triangles", "triangles_adjacency" }; 4239e5c31af7Sopenharmony_ci const std::string gs_outputs[] = { "points", "line_strip", "triangle_strip" }; 4240e5c31af7Sopenharmony_ci const std::string gs_max_output_vertices[] = { "1", "2", "3" }; 4241e5c31af7Sopenharmony_ci 4242e5c31af7Sopenharmony_ci const unsigned short number_of_combinations = 4243e5c31af7Sopenharmony_ci (sizeof(gs_inputs) / sizeof(gs_inputs[0]) * (sizeof(gs_outputs) / sizeof(gs_outputs[0]))); 4244e5c31af7Sopenharmony_ci 4245e5c31af7Sopenharmony_ci std::string gs_codes[number_of_combinations]; 4246e5c31af7Sopenharmony_ci glw::GLenum errorCode; 4247e5c31af7Sopenharmony_ci 4248e5c31af7Sopenharmony_ci for (size_t i = 0; i < (sizeof(gs_inputs) / sizeof(gs_inputs[0])) /*5 possible GS inputs*/; ++i) 4249e5c31af7Sopenharmony_ci { 4250e5c31af7Sopenharmony_ci for (size_t j = 0; j < (sizeof(gs_outputs) / sizeof(gs_outputs[0])) /*3 possible GS outputs*/; ++j) 4251e5c31af7Sopenharmony_ci { 4252e5c31af7Sopenharmony_ci /* This shader will not emit primitives for anything but points. 4253e5c31af7Sopenharmony_ci * We do so, because we just need to make sure that, while transform feedback 4254e5c31af7Sopenharmony_ci * is paused, all draw calls executed with an active program object which 4255e5c31af7Sopenharmony_ci * includes a geometry shader, are valid. 4256e5c31af7Sopenharmony_ci */ 4257e5c31af7Sopenharmony_ci gs_codes[j + 3 * i] = "${VERSION}\n" 4258e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 4259e5c31af7Sopenharmony_ci "\n" 4260e5c31af7Sopenharmony_ci "layout (" + 4261e5c31af7Sopenharmony_ci gs_inputs[i] + ") in;\n" 4262e5c31af7Sopenharmony_ci "layout (" + 4263e5c31af7Sopenharmony_ci gs_outputs[j] + ", max_vertices = " + gs_max_output_vertices[j] + 4264e5c31af7Sopenharmony_ci ") out;\n" 4265e5c31af7Sopenharmony_ci "\n" 4266e5c31af7Sopenharmony_ci "out vec2 out_gs_1;\n" 4267e5c31af7Sopenharmony_ci "\n" 4268e5c31af7Sopenharmony_ci "void main()\n" 4269e5c31af7Sopenharmony_ci "{\n" 4270e5c31af7Sopenharmony_ci " out_gs_1 = vec2(1.0, 2.0);\n" 4271e5c31af7Sopenharmony_ci " gl_Position = vec4(0, 0, 0, 1);\n" 4272e5c31af7Sopenharmony_ci " EmitVertex();\n" 4273e5c31af7Sopenharmony_ci "}\n"; 4274e5c31af7Sopenharmony_ci } 4275e5c31af7Sopenharmony_ci } 4276e5c31af7Sopenharmony_ci 4277e5c31af7Sopenharmony_ci bool has_shader_compilation_failed = true; 4278e5c31af7Sopenharmony_ci bool result = true; 4279e5c31af7Sopenharmony_ci const glw::GLuint tf_modes[3] = { GL_POINTS, GL_LINES, GL_TRIANGLES }; 4280e5c31af7Sopenharmony_ci const glw::GLuint draw_call_modes[5] = { GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, 4281e5c31af7Sopenharmony_ci GL_TRIANGLES_ADJACENCY }; 4282e5c31af7Sopenharmony_ci 4283e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported. */ 4284e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 4285e5c31af7Sopenharmony_ci { 4286e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 4287e5c31af7Sopenharmony_ci } 4288e5c31af7Sopenharmony_ci 4289e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 4290e5c31af7Sopenharmony_ci 4291e5c31af7Sopenharmony_ci /* Create program objects. */ 4292e5c31af7Sopenharmony_ci for (int i = 0; i < number_of_combinations; ++i) 4293e5c31af7Sopenharmony_ci { 4294e5c31af7Sopenharmony_ci m_po_ids[i] = gl.createProgram(); 4295e5c31af7Sopenharmony_ci } 4296e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed."); 4297e5c31af7Sopenharmony_ci 4298e5c31af7Sopenharmony_ci /* Specify output variables to be captured. */ 4299e5c31af7Sopenharmony_ci const char* tf_varyings[] = { "out_gs_1" }; 4300e5c31af7Sopenharmony_ci 4301e5c31af7Sopenharmony_ci for (int i = 0; i < number_of_combinations; ++i) 4302e5c31af7Sopenharmony_ci { 4303e5c31af7Sopenharmony_ci gl.transformFeedbackVaryings(m_po_ids[i], 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS); 4304e5c31af7Sopenharmony_ci } 4305e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed."); 4306e5c31af7Sopenharmony_ci 4307e5c31af7Sopenharmony_ci /* Create shader objects. */ 4308e5c31af7Sopenharmony_ci m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); 4309e5c31af7Sopenharmony_ci m_gs_id = gl.createShader(GL_GEOMETRY_SHADER); 4310e5c31af7Sopenharmony_ci m_vs_id = gl.createShader(GL_VERTEX_SHADER); 4311e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed."); 4312e5c31af7Sopenharmony_ci 4313e5c31af7Sopenharmony_ci /* Try to link the test program object */ 4314e5c31af7Sopenharmony_ci std::string fs_code_specialized = specializeShader(1, &minimal_fs_code); 4315e5c31af7Sopenharmony_ci const char* fs_code_specialized_raw = fs_code_specialized.c_str(); 4316e5c31af7Sopenharmony_ci 4317e5c31af7Sopenharmony_ci std::string vs_code_specialized = specializeShader(1, &minimal_vs_code); 4318e5c31af7Sopenharmony_ci const char* vs_code_specialized_raw = vs_code_specialized.c_str(); 4319e5c31af7Sopenharmony_ci 4320e5c31af7Sopenharmony_ci for (int i = 0; i < number_of_combinations; ++i) 4321e5c31af7Sopenharmony_ci { 4322e5c31af7Sopenharmony_ci const char* gs_code = gs_codes[i].c_str(); 4323e5c31af7Sopenharmony_ci std::string gs_code_specialized = specializeShader(1, &gs_code); 4324e5c31af7Sopenharmony_ci const char* gs_code_specialized_raw = gs_code_specialized.c_str(); 4325e5c31af7Sopenharmony_ci 4326e5c31af7Sopenharmony_ci if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */ 4327e5c31af7Sopenharmony_ci &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */ 4328e5c31af7Sopenharmony_ci &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */ 4329e5c31af7Sopenharmony_ci &vs_code_specialized_raw, &has_shader_compilation_failed)) 4330e5c31af7Sopenharmony_ci { 4331e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 4332e5c31af7Sopenharmony_ci << "Program object linking failed whereas a success was expected." 4333e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 4334e5c31af7Sopenharmony_ci 4335e5c31af7Sopenharmony_ci result = false; 4336e5c31af7Sopenharmony_ci } 4337e5c31af7Sopenharmony_ci } 4338e5c31af7Sopenharmony_ci 4339e5c31af7Sopenharmony_ci if (!result) 4340e5c31af7Sopenharmony_ci { 4341e5c31af7Sopenharmony_ci goto end; 4342e5c31af7Sopenharmony_ci } 4343e5c31af7Sopenharmony_ci 4344e5c31af7Sopenharmony_ci /* Create Vertex Array Object. */ 4345e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 4346e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed."); 4347e5c31af7Sopenharmony_ci 4348e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 4349e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed."); 4350e5c31af7Sopenharmony_ci 4351e5c31af7Sopenharmony_ci /* Create Buffer Object for Transform Feedback data. */ 4352e5c31af7Sopenharmony_ci gl.genBuffers(1, &m_tfbo_id); 4353e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed."); 4354e5c31af7Sopenharmony_ci 4355e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id); 4356e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed."); 4357e5c31af7Sopenharmony_ci 4358e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, 4359e5c31af7Sopenharmony_ci sizeof(glw::GLfloat) * 2 * 3 /* capture 2 float vector components times 3 triangle vertices */, NULL, 4360e5c31af7Sopenharmony_ci GL_STREAM_READ); 4361e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed."); 4362e5c31af7Sopenharmony_ci 4363e5c31af7Sopenharmony_ci gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id); 4364e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed."); 4365e5c31af7Sopenharmony_ci 4366e5c31af7Sopenharmony_ci gl.enable(GL_RASTERIZER_DISCARD); 4367e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed."); 4368e5c31af7Sopenharmony_ci 4369e5c31af7Sopenharmony_ci for (int i = 0; i < 3 /* number of TF modes */ && result; ++i) 4370e5c31af7Sopenharmony_ci { 4371e5c31af7Sopenharmony_ci for (int j = 0; j < 5 /*number of draw call modes*/ && result; ++j) 4372e5c31af7Sopenharmony_ci { 4373e5c31af7Sopenharmony_ci for (int k = 0; k < 3 /* number of output GS primitive types */; ++k) 4374e5c31af7Sopenharmony_ci { 4375e5c31af7Sopenharmony_ci /* Turn on program object. */ 4376e5c31af7Sopenharmony_ci gl.useProgram(m_po_ids[k + 3 * j]); 4377e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed."); 4378e5c31af7Sopenharmony_ci 4379e5c31af7Sopenharmony_ci gl.beginTransformFeedback(tf_modes[i]); 4380e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed."); 4381e5c31af7Sopenharmony_ci 4382e5c31af7Sopenharmony_ci gl.pauseTransformFeedback(); 4383e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback() call(s) failed."); 4384e5c31af7Sopenharmony_ci 4385e5c31af7Sopenharmony_ci gl.drawArrays(draw_call_modes[j], 0 /*first*/, 3 /*count*/); 4386e5c31af7Sopenharmony_ci errorCode = gl.getError(); 4387e5c31af7Sopenharmony_ci 4388e5c31af7Sopenharmony_ci gl.resumeTransformFeedback(); 4389e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback() call(s) failed."); 4390e5c31af7Sopenharmony_ci 4391e5c31af7Sopenharmony_ci gl.endTransformFeedback(); 4392e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed."); 4393e5c31af7Sopenharmony_ci 4394e5c31af7Sopenharmony_ci /* If draw call fails stop test execution. */ 4395e5c31af7Sopenharmony_ci if (GL_NO_ERROR != errorCode) 4396e5c31af7Sopenharmony_ci { 4397e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message 4398e5c31af7Sopenharmony_ci << "glDrawArrays() call generated an error while transform feedback was paused." 4399e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 4400e5c31af7Sopenharmony_ci 4401e5c31af7Sopenharmony_ci result = false; 4402e5c31af7Sopenharmony_ci break; 4403e5c31af7Sopenharmony_ci } 4404e5c31af7Sopenharmony_ci } 4405e5c31af7Sopenharmony_ci } 4406e5c31af7Sopenharmony_ci } 4407e5c31af7Sopenharmony_ci 4408e5c31af7Sopenharmony_ci gl.disable(GL_RASTERIZER_DISCARD); 4409e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed."); 4410e5c31af7Sopenharmony_ci 4411e5c31af7Sopenharmony_ciend: 4412e5c31af7Sopenharmony_ci 4413e5c31af7Sopenharmony_ci if (result) 4414e5c31af7Sopenharmony_ci { 4415e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4416e5c31af7Sopenharmony_ci } 4417e5c31af7Sopenharmony_ci else 4418e5c31af7Sopenharmony_ci { 4419e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4420e5c31af7Sopenharmony_ci } 4421e5c31af7Sopenharmony_ci 4422e5c31af7Sopenharmony_ci return STOP; 4423e5c31af7Sopenharmony_ci} 4424e5c31af7Sopenharmony_ci 4425e5c31af7Sopenharmony_ci} // namespace glcts 4426