1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014-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 24e5c31af7Sopenharmony_ci#include "esextcGeometryShaderLayeredRendering.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 27e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 28e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 29e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 30e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include <algorithm> 33e5c31af7Sopenharmony_ci#include <cstring> 34e5c31af7Sopenharmony_ci#include <string> 35e5c31af7Sopenharmony_ci#include <vector> 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_cinamespace glcts 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_ci/* Array holding vector values describing contents of layers 40e5c31af7Sopenharmony_ci * at subsequent indices. 41e5c31af7Sopenharmony_ci * 42e5c31af7Sopenharmony_ci * Contents of this array are directly related to layered_rendering_fs_code. 43e5c31af7Sopenharmony_ci **/ 44e5c31af7Sopenharmony_ciconst unsigned char GeometryShaderLayeredRendering::m_layered_rendering_expected_layer_data[6 * 4] = { 45e5c31af7Sopenharmony_ci /* Layer 0 */ 46e5c31af7Sopenharmony_ci 255, 0, 0, 0, 47e5c31af7Sopenharmony_ci /* Layer 1 */ 48e5c31af7Sopenharmony_ci 0, 255, 0, 0, 49e5c31af7Sopenharmony_ci /* Layer 2 */ 50e5c31af7Sopenharmony_ci 0, 0, 255, 0, 51e5c31af7Sopenharmony_ci /* Layer 3 */ 52e5c31af7Sopenharmony_ci 0, 0, 0, 255, 53e5c31af7Sopenharmony_ci /* Layer 4 */ 54e5c31af7Sopenharmony_ci 255, 255, 0, 0, 55e5c31af7Sopenharmony_ci /* Layer 5 */ 56e5c31af7Sopenharmony_ci 255, 0, 255, 0 57e5c31af7Sopenharmony_ci}; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ci/* Fragment shader code */ 60e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_fs_code = 61e5c31af7Sopenharmony_ci "${VERSION}\n" 62e5c31af7Sopenharmony_ci "\n" 63e5c31af7Sopenharmony_ci "precision highp float;\n" 64e5c31af7Sopenharmony_ci "\n" 65e5c31af7Sopenharmony_ci "flat in int layer_id;\n" 66e5c31af7Sopenharmony_ci " out vec4 color;\n" 67e5c31af7Sopenharmony_ci "\n" 68e5c31af7Sopenharmony_ci "void main()\n" 69e5c31af7Sopenharmony_ci "{\n" 70e5c31af7Sopenharmony_ci " switch (layer_id)\n" 71e5c31af7Sopenharmony_ci " {\n" 72e5c31af7Sopenharmony_ci " case 0: color = vec4(1, 0, 0, 0); break;\n" 73e5c31af7Sopenharmony_ci " case 1: color = vec4(0, 1, 0, 0); break;\n" 74e5c31af7Sopenharmony_ci " case 2: color = vec4(0, 0, 1, 0); break;\n" 75e5c31af7Sopenharmony_ci " case 3: color = vec4(0, 0, 0, 1); break;\n" 76e5c31af7Sopenharmony_ci " case 4: color = vec4(1, 1, 0, 0); break;\n" 77e5c31af7Sopenharmony_ci " case 5: color = vec4(1, 0, 1, 0); break;\n" 78e5c31af7Sopenharmony_ci " default: color = vec4(1, 1, 1, 1); break;\n" 79e5c31af7Sopenharmony_ci " }\n" 80e5c31af7Sopenharmony_ci "}\n"; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci/* Geometry shader code parts */ 83e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_preamble = "${VERSION}\n" 84e5c31af7Sopenharmony_ci "${GEOMETRY_SHADER_REQUIRE}\n" 85e5c31af7Sopenharmony_ci "\n"; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_2d_array = "#define MAX_VERTICES 64\n" 88e5c31af7Sopenharmony_ci "#define N_LAYERS 4\n"; 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_2d_marray = "#define MAX_VERTICES 64\n" 91e5c31af7Sopenharmony_ci "#define N_LAYERS 4\n"; 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_3d = "#define MAX_VERTICES 64\n" 94e5c31af7Sopenharmony_ci "#define N_LAYERS 4\n"; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_cm = "#define MAX_VERTICES 96\n" 97e5c31af7Sopenharmony_ci "#define N_LAYERS 6\n"; 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci/* NOTE: provoking_vertex_index holds an integer value which represents platform-reported 100e5c31af7Sopenharmony_ci * GL_LAYER_PROVOKING_VERTEX_EXT value. The meaning is as follows: 101e5c31af7Sopenharmony_ci * 102e5c31af7Sopenharmony_ci * 0: Property carries a GL_UNDEFINED_VERTEX_EXT value. Need to set gl_Layer for all 103e5c31af7Sopenharmony_ci * vertices. 104e5c31af7Sopenharmony_ci * 1: Property carries a GL_FIRST_VERTEX_CONVENTION_EXT value. Need to set gl_Layer for 105e5c31af7Sopenharmony_ci * the first two vertices, since these are a part of the two triangles, emitted 106e5c31af7Sopenharmony_ci * separately for each layer. 107e5c31af7Sopenharmony_ci * 2: Property carries a GL_LAST_VERTEX_CONVENTION_EXT value. Need to set gl_Layer for 108e5c31af7Sopenharmony_ci * the last two vertices, since these are a part of the two triangles, emitted 109e5c31af7Sopenharmony_ci * separately for each layer. 110e5c31af7Sopenharmony_ci */ 111e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_gs_code_main = 112e5c31af7Sopenharmony_ci "layout(points) in;\n" 113e5c31af7Sopenharmony_ci "layout(triangle_strip, max_vertices=MAX_VERTICES) out;\n" 114e5c31af7Sopenharmony_ci "\n" 115e5c31af7Sopenharmony_ci "precision highp float;\n" 116e5c31af7Sopenharmony_ci "\n" 117e5c31af7Sopenharmony_ci "flat out int layer_id;\n" 118e5c31af7Sopenharmony_ci "uniform int provoking_vertex_index;\n" 119e5c31af7Sopenharmony_ci "\n" 120e5c31af7Sopenharmony_ci "void main()\n" 121e5c31af7Sopenharmony_ci "{\n" 122e5c31af7Sopenharmony_ci " for (int n = 0; n < N_LAYERS; ++n)\n" 123e5c31af7Sopenharmony_ci " {\n" 124e5c31af7Sopenharmony_ci " #ifndef SHOULD_NOT_SET_GL_LAYER\n" 125e5c31af7Sopenharmony_ci " if (provoking_vertex_index == 0 || provoking_vertex_index == 1) gl_Layer = n;\n" 126e5c31af7Sopenharmony_ci " #endif\n" 127e5c31af7Sopenharmony_ci "\n" 128e5c31af7Sopenharmony_ci " layer_id = gl_Layer;\n" 129e5c31af7Sopenharmony_ci " gl_Position = vec4(1, 1, 0, 1);\n" 130e5c31af7Sopenharmony_ci " EmitVertex();\n" 131e5c31af7Sopenharmony_ci "\n" 132e5c31af7Sopenharmony_ci " #ifndef SHOULD_NOT_SET_GL_LAYER\n" 133e5c31af7Sopenharmony_ci " if (provoking_vertex_index == 0 || provoking_vertex_index == 1) gl_Layer = n;\n" 134e5c31af7Sopenharmony_ci " #endif\n" 135e5c31af7Sopenharmony_ci "\n" 136e5c31af7Sopenharmony_ci " layer_id = gl_Layer;\n" 137e5c31af7Sopenharmony_ci " gl_Position = vec4(1, -1, 0, 1);\n" 138e5c31af7Sopenharmony_ci " EmitVertex();\n" 139e5c31af7Sopenharmony_ci "\n" 140e5c31af7Sopenharmony_ci " #ifndef SHOULD_NOT_SET_GL_LAYER\n" 141e5c31af7Sopenharmony_ci " if (provoking_vertex_index == 0 || provoking_vertex_index == 2) gl_Layer = n;\n" 142e5c31af7Sopenharmony_ci " #endif\n" 143e5c31af7Sopenharmony_ci "\n" 144e5c31af7Sopenharmony_ci " layer_id = gl_Layer;\n" 145e5c31af7Sopenharmony_ci " gl_Position = vec4(-1, 1, 0, 1);\n" 146e5c31af7Sopenharmony_ci " EmitVertex();\n" 147e5c31af7Sopenharmony_ci "\n" 148e5c31af7Sopenharmony_ci " #ifndef SHOULD_NOT_SET_GL_LAYER\n" 149e5c31af7Sopenharmony_ci " gl_Layer = n;\n" 150e5c31af7Sopenharmony_ci " #endif\n" 151e5c31af7Sopenharmony_ci "\n" 152e5c31af7Sopenharmony_ci " layer_id = gl_Layer;\n" 153e5c31af7Sopenharmony_ci " gl_Position = vec4(-1, -1, 0, 1);\n" 154e5c31af7Sopenharmony_ci " EmitVertex();\n" 155e5c31af7Sopenharmony_ci "\n" 156e5c31af7Sopenharmony_ci " EndPrimitive();\n" 157e5c31af7Sopenharmony_ci " }\n" 158e5c31af7Sopenharmony_ci "}\n"; 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci/* Vertex shader */ 161e5c31af7Sopenharmony_ciconst char* GeometryShaderLayeredRendering::m_layered_rendering_vs_code = "${VERSION}\n" 162e5c31af7Sopenharmony_ci "\n" 163e5c31af7Sopenharmony_ci "precision highp float;\n" 164e5c31af7Sopenharmony_ci "\n" 165e5c31af7Sopenharmony_ci "flat out int layer_id;\n" 166e5c31af7Sopenharmony_ci "void main()\n" 167e5c31af7Sopenharmony_ci "{\n" 168e5c31af7Sopenharmony_ci " layer_id = 0;\n" 169e5c31af7Sopenharmony_ci "}\n"; 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci/* Constants used for various test iterations */ 172e5c31af7Sopenharmony_ci#define TEXTURE_DEPTH (64) 173e5c31af7Sopenharmony_ci#define TEXTURE_HEIGHT (32) 174e5c31af7Sopenharmony_ci#define TEXTURE_N_COMPONENTS (4) 175e5c31af7Sopenharmony_ci#define TEXTURE_WIDTH (32) 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci/* Constructor */ 178e5c31af7Sopenharmony_ciGeometryShaderLayeredRendering::GeometryShaderLayeredRendering(Context& context, const ExtParameters& extParams, 179e5c31af7Sopenharmony_ci const char* name, const char* description) 180e5c31af7Sopenharmony_ci : TestCaseBase(context, extParams, name, description), m_vao_id(0) 181e5c31af7Sopenharmony_ci{ 182e5c31af7Sopenharmony_ci memset(m_tests, 0, sizeof(m_tests)); 183e5c31af7Sopenharmony_ci} 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci/** Builds a GL program specifically for a layer rendering test instance. 186e5c31af7Sopenharmony_ci * 187e5c31af7Sopenharmony_ci * @param test Layered Rendering test to consider. 188e5c31af7Sopenharmony_ci * 189e5c31af7Sopenharmony_ci * @return GTFtrue if successful, false otherwise. 190e5c31af7Sopenharmony_ci **/ 191e5c31af7Sopenharmony_cibool GeometryShaderLayeredRendering::buildProgramForLRTest(_layered_rendering_test* test) 192e5c31af7Sopenharmony_ci{ 193e5c31af7Sopenharmony_ci return buildProgram(test->po_id, test->fs_id, test->n_fs_parts, test->fs_parts, test->gs_id, test->n_gs_parts, 194e5c31af7Sopenharmony_ci test->gs_parts, test->vs_id, test->n_vs_parts, test->vs_parts); 195e5c31af7Sopenharmony_ci} 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ci/** Executes the test. 198e5c31af7Sopenharmony_ci * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. 199e5c31af7Sopenharmony_ci * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again. 200e5c31af7Sopenharmony_ci * Note the function throws exception should an error occur! 201e5c31af7Sopenharmony_ci **/ 202e5c31af7Sopenharmony_citcu::TestNode::IterateResult GeometryShaderLayeredRendering::iterate(void) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci const glu::ContextType& context_type = m_context.getRenderContext().getType(); 205e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ci /* Helper variables to support shader compilation process */ 208e5c31af7Sopenharmony_ci const char* cm_fs_parts[] = { m_layered_rendering_fs_code }; 209e5c31af7Sopenharmony_ci const char* cm_gs_parts[] = { m_layered_rendering_gs_code_preamble, m_layered_rendering_gs_code_cm, 210e5c31af7Sopenharmony_ci m_layered_rendering_gs_code_main }; 211e5c31af7Sopenharmony_ci const char* cm_vs_parts[] = { m_layered_rendering_vs_code }; 212e5c31af7Sopenharmony_ci const char* threedimensional_fs_parts[] = { m_layered_rendering_fs_code }; 213e5c31af7Sopenharmony_ci const char* threedimensional_gs_parts[] = { m_layered_rendering_gs_code_preamble, m_layered_rendering_gs_code_3d, 214e5c31af7Sopenharmony_ci m_layered_rendering_gs_code_main }; 215e5c31af7Sopenharmony_ci const char* threedimensional_vs_parts[] = { m_layered_rendering_vs_code }; 216e5c31af7Sopenharmony_ci const char* twodimensionala_fs_parts[] = { m_layered_rendering_fs_code }; 217e5c31af7Sopenharmony_ci const char* twodimensionala_gs_parts[] = { m_layered_rendering_gs_code_preamble, 218e5c31af7Sopenharmony_ci m_layered_rendering_gs_code_2d_array, m_layered_rendering_gs_code_main }; 219e5c31af7Sopenharmony_ci const char* twodimensionala_vs_parts[] = { m_layered_rendering_vs_code }; 220e5c31af7Sopenharmony_ci const char* twodimensionalma_fs_parts[] = { m_layered_rendering_fs_code }; 221e5c31af7Sopenharmony_ci const char* twodimensionalma_gs_parts[] = { m_layered_rendering_gs_code_preamble, 222e5c31af7Sopenharmony_ci m_layered_rendering_gs_code_2d_marray, 223e5c31af7Sopenharmony_ci m_layered_rendering_gs_code_main }; 224e5c31af7Sopenharmony_ci const char* twodimensionalma_vs_parts[] = { m_layered_rendering_vs_code }; 225e5c31af7Sopenharmony_ci const unsigned int n_cm_fs_parts = sizeof(cm_fs_parts) / sizeof(cm_fs_parts[0]); 226e5c31af7Sopenharmony_ci const unsigned int n_cm_gs_parts = sizeof(cm_gs_parts) / sizeof(cm_gs_parts[0]); 227e5c31af7Sopenharmony_ci const unsigned int n_cm_vs_parts = sizeof(cm_vs_parts) / sizeof(cm_vs_parts[0]); 228e5c31af7Sopenharmony_ci const unsigned int n_threedimensional_fs_parts = 229e5c31af7Sopenharmony_ci sizeof(threedimensional_fs_parts) / sizeof(threedimensional_fs_parts[0]); 230e5c31af7Sopenharmony_ci const unsigned int n_threedimensional_gs_parts = 231e5c31af7Sopenharmony_ci sizeof(threedimensional_gs_parts) / sizeof(threedimensional_gs_parts[0]); 232e5c31af7Sopenharmony_ci const unsigned int n_threedimensional_vs_parts = 233e5c31af7Sopenharmony_ci sizeof(threedimensional_vs_parts) / sizeof(threedimensional_vs_parts[0]); 234e5c31af7Sopenharmony_ci const unsigned int n_twodimensionala_fs_parts = 235e5c31af7Sopenharmony_ci sizeof(twodimensionala_fs_parts) / sizeof(twodimensionala_fs_parts[0]); 236e5c31af7Sopenharmony_ci const unsigned int n_twodimensionala_gs_parts = 237e5c31af7Sopenharmony_ci sizeof(twodimensionala_gs_parts) / sizeof(twodimensionala_gs_parts[0]); 238e5c31af7Sopenharmony_ci const unsigned int n_twodimensionala_vs_parts = 239e5c31af7Sopenharmony_ci sizeof(twodimensionala_vs_parts) / sizeof(twodimensionala_vs_parts[0]); 240e5c31af7Sopenharmony_ci const unsigned int n_twodimensionalma_fs_parts = 241e5c31af7Sopenharmony_ci sizeof(twodimensionalma_fs_parts) / sizeof(twodimensionalma_fs_parts[0]); 242e5c31af7Sopenharmony_ci const unsigned int n_twodimensionalma_gs_parts = 243e5c31af7Sopenharmony_ci sizeof(twodimensionalma_gs_parts) / sizeof(twodimensionalma_gs_parts[0]); 244e5c31af7Sopenharmony_ci const unsigned int n_twodimensionalma_vs_parts = 245e5c31af7Sopenharmony_ci sizeof(twodimensionalma_vs_parts) / sizeof(twodimensionalma_vs_parts[0]); 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci /* General-use helper variables */ 248e5c31af7Sopenharmony_ci unsigned int n_current_test = 0; 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci /* This test should only run if EXT_geometry_shader is supported */ 251e5c31af7Sopenharmony_ci if (!m_is_geometry_shader_extension_supported) 252e5c31af7Sopenharmony_ci { 253e5c31af7Sopenharmony_ci throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); 254e5c31af7Sopenharmony_ci } 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci /* Configure test descriptors */ 257e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].iteration = LAYERED_RENDERING_TEST_ITERATION_CUBEMAP; 258e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].n_layers = 6; /* faces */ 259e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].fs_parts = cm_fs_parts; 260e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].gs_parts = cm_gs_parts; 261e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].vs_parts = cm_vs_parts; 262e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].n_fs_parts = n_cm_fs_parts; 263e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].n_gs_parts = n_cm_gs_parts; 264e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].n_vs_parts = n_cm_vs_parts; 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].iteration = LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY; 267e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].n_layers = 4; /* layers */ 268e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].fs_parts = twodimensionala_fs_parts; 269e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].gs_parts = twodimensionala_gs_parts; 270e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].vs_parts = twodimensionala_vs_parts; 271e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].n_fs_parts = n_twodimensionala_fs_parts; 272e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].n_gs_parts = n_twodimensionala_gs_parts; 273e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].n_vs_parts = n_twodimensionala_vs_parts; 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].iteration = LAYERED_RENDERING_TEST_ITERATION_3D; 276e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].n_layers = 4; /* layers */ 277e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].fs_parts = threedimensional_fs_parts; 278e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].gs_parts = threedimensional_gs_parts; 279e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].vs_parts = threedimensional_vs_parts; 280e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].n_fs_parts = n_threedimensional_fs_parts; 281e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].n_gs_parts = n_threedimensional_gs_parts; 282e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].n_vs_parts = n_threedimensional_vs_parts; 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].iteration = 285e5c31af7Sopenharmony_ci LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY; 286e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].n_layers = 4; /* layers */ 287e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].fs_parts = twodimensionalma_fs_parts; 288e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].gs_parts = twodimensionalma_gs_parts; 289e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].vs_parts = twodimensionalma_vs_parts; 290e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].n_fs_parts = n_twodimensionalma_fs_parts; 291e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].n_gs_parts = n_twodimensionalma_gs_parts; 292e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].n_vs_parts = n_twodimensionalma_vs_parts; 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci /* Create shader objects we'll use for the test */ 295e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].fs_id = gl.createShader(GL_FRAGMENT_SHADER); 296e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 297e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].vs_id = gl.createShader(GL_VERTEX_SHADER); 298e5c31af7Sopenharmony_ci 299e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].fs_id = gl.createShader(GL_FRAGMENT_SHADER); 300e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 301e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].vs_id = gl.createShader(GL_VERTEX_SHADER); 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].fs_id = gl.createShader(GL_FRAGMENT_SHADER); 304e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 305e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].vs_id = gl.createShader(GL_VERTEX_SHADER); 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].fs_id = gl.createShader(GL_FRAGMENT_SHADER); 308e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].gs_id = 309e5c31af7Sopenharmony_ci gl.createShader(m_glExtTokens.GEOMETRY_SHADER); 310e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].vs_id = gl.createShader(GL_VERTEX_SHADER); 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shaders!"); 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci /* Create program objects as well */ 315e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].po_id = gl.createProgram(); 316e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].po_id = gl.createProgram(); 317e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].po_id = gl.createProgram(); 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].po_id = gl.createProgram(); 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create programs!"); 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci /* Build the programs */ 324e5c31af7Sopenharmony_ci if (!buildProgramForLRTest(&m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP]) || 325e5c31af7Sopenharmony_ci !buildProgramForLRTest(&m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY]) || 326e5c31af7Sopenharmony_ci !buildProgramForLRTest(&m_tests[LAYERED_RENDERING_TEST_ITERATION_3D]) || 327e5c31af7Sopenharmony_ci !buildProgramForLRTest(&m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY])) 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci TCU_FAIL("Could not create a program for cube-map texture layered rendering test!"); 330e5c31af7Sopenharmony_ci } 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci /* Set up provoking vertex uniform value, given the GL_LAYER_PROVOKING_VERTEX_EXT value. */ 333e5c31af7Sopenharmony_ci glw::GLint layer_provoking_vertex_gl_value = -1; 334e5c31af7Sopenharmony_ci glw::GLint layer_provoking_vertex_uniform_value = -1; 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_ci gl.getIntegerv(m_glExtTokens.LAYER_PROVOKING_VERTEX, &layer_provoking_vertex_gl_value); 337e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_LAYER_PROVOKING_VERTEX_EXT pname"); 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci if (!glu::isContextTypeES(context_type) && ((glw::GLenum)layer_provoking_vertex_gl_value == GL_PROVOKING_VERTEX)) 340e5c31af7Sopenharmony_ci { 341e5c31af7Sopenharmony_ci gl.getIntegerv(GL_PROVOKING_VERTEX, &layer_provoking_vertex_gl_value); 342e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_PROVOKING_VERTEX pname"); 343e5c31af7Sopenharmony_ci } 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci if ((glw::GLenum)layer_provoking_vertex_gl_value == m_glExtTokens.FIRST_VERTEX_CONVENTION) 346e5c31af7Sopenharmony_ci { 347e5c31af7Sopenharmony_ci layer_provoking_vertex_uniform_value = 1; /* as per geometry shader implementation */ 348e5c31af7Sopenharmony_ci } 349e5c31af7Sopenharmony_ci else if ((glw::GLenum)layer_provoking_vertex_gl_value == m_glExtTokens.LAST_VERTEX_CONVENTION) 350e5c31af7Sopenharmony_ci { 351e5c31af7Sopenharmony_ci layer_provoking_vertex_uniform_value = 2; /* as per geometry shader implementation */ 352e5c31af7Sopenharmony_ci } 353e5c31af7Sopenharmony_ci else if ((glw::GLenum)layer_provoking_vertex_gl_value == m_glExtTokens.UNDEFINED_VERTEX) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci layer_provoking_vertex_uniform_value = 0; /* as per geometry shader implementation */ 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci else 358e5c31af7Sopenharmony_ci { 359e5c31af7Sopenharmony_ci TCU_FAIL("Unrecognized value returned by glGetIntegerv() for GL_LAYER_PROVOKING_VERTEX_EXT pname."); 360e5c31af7Sopenharmony_ci } 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci for (unsigned int test_index = 0; test_index < LAYERED_RENDERING_TEST_ITERATION_LAST; ++test_index) 363e5c31af7Sopenharmony_ci { 364e5c31af7Sopenharmony_ci glw::GLint provoking_vertex_index_uniform_location = 365e5c31af7Sopenharmony_ci gl.getUniformLocation(m_tests[test_index].po_id, "provoking_vertex_index"); 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci /* Quick checks */ 368e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call generated an error"); 369e5c31af7Sopenharmony_ci DE_ASSERT(provoking_vertex_index_uniform_location != -1); 370e5c31af7Sopenharmony_ci 371e5c31af7Sopenharmony_ci /* Assign the uniform value */ 372e5c31af7Sopenharmony_ci gl.programUniform1i(m_tests[test_index].po_id, provoking_vertex_index_uniform_location, 373e5c31af7Sopenharmony_ci layer_provoking_vertex_uniform_value); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramUniform1i() call failed."); 376e5c31af7Sopenharmony_ci } /* for (all test iterations) */ 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci /* Initialize texture objects */ 379e5c31af7Sopenharmony_ci gl.genTextures(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].to_id); 380e5c31af7Sopenharmony_ci gl.genTextures(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].to_id); 381e5c31af7Sopenharmony_ci gl.genTextures(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].to_id); 382e5c31af7Sopenharmony_ci gl.genTextures(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].to_id); 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create texture object(s)!"); 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].to_id); 387e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1 /* mip-map only */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT); 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].to_id); 390e5c31af7Sopenharmony_ci gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* mip-map only */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH); 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_3D, m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].to_id); 393e5c31af7Sopenharmony_ci gl.texStorage3D(GL_TEXTURE_3D, 1 /* mip-map only */, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH); 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 396e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].to_id); 397e5c31af7Sopenharmony_ci gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 1 /* samples */, GL_RGBA8, TEXTURE_WIDTH, 398e5c31af7Sopenharmony_ci TEXTURE_HEIGHT, TEXTURE_DEPTH, GL_FALSE /* fixed sample locations */); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not initialize texture object(s)!"); 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci /* Initialize framebuffer objects */ 403e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].fbo_id); 404e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].fbo_id); 405e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].fbo_id); 406e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].fbo_id); 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer object(s)!"); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].fbo_id); 411e5c31af7Sopenharmony_ci gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 412e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_CUBEMAP].to_id, 0 /* base mip-map */); 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].fbo_id); 415e5c31af7Sopenharmony_ci gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 416e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY].to_id, 0 /* base mip-map */); 417e5c31af7Sopenharmony_ci 418e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].fbo_id); 419e5c31af7Sopenharmony_ci gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_tests[LAYERED_RENDERING_TEST_ITERATION_3D].to_id, 420e5c31af7Sopenharmony_ci 0 /* base mip-map */); 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].fbo_id); 423e5c31af7Sopenharmony_ci gl.framebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 424e5c31af7Sopenharmony_ci m_tests[LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY].to_id, 0 /* base mip-map */); 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not configure framebuffer object(s)!"); 427e5c31af7Sopenharmony_ci 428e5c31af7Sopenharmony_ci /* Initialize vertex array object. We don't really use any attributes, but ES does not 429e5c31af7Sopenharmony_ci * permit draw calls with an unbound VAO 430e5c31af7Sopenharmony_ci */ 431e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &m_vao_id); 432e5c31af7Sopenharmony_ci gl.bindVertexArray(m_vao_id); 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind a vertex array object!"); 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci /* Execute all iterations */ 437e5c31af7Sopenharmony_ci for (n_current_test = 0; n_current_test < sizeof(m_tests) / sizeof(m_tests[0]); ++n_current_test) 438e5c31af7Sopenharmony_ci { 439e5c31af7Sopenharmony_ci unsigned char buffer[TEXTURE_WIDTH * TEXTURE_HEIGHT * TEXTURE_N_COMPONENTS] = { 0 }; 440e5c31af7Sopenharmony_ci glw::GLuint program_id = 0; 441e5c31af7Sopenharmony_ci unsigned int n_layer = 0; 442e5c31af7Sopenharmony_ci glw::GLuint texture_id = 0; 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci /* Bind the iteration-specific framebuffer */ 445e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_tests[n_current_test].fbo_id); 446e5c31af7Sopenharmony_ci 447e5c31af7Sopenharmony_ci program_id = m_tests[n_current_test].po_id; 448e5c31af7Sopenharmony_ci texture_id = m_tests[n_current_test].to_id; 449e5c31af7Sopenharmony_ci 450e5c31af7Sopenharmony_ci /* Clear the color attachment with (1, 1, 1, 1) which is not used for 451e5c31af7Sopenharmony_ci * any layers. 452e5c31af7Sopenharmony_ci */ 453e5c31af7Sopenharmony_ci gl.clearColor(1.0f, 1.0f, 1.0f, 1.0f); 454e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 455e5c31af7Sopenharmony_ci 456e5c31af7Sopenharmony_ci /* Render a single point. This should result in full-screen quads drawn 457e5c31af7Sopenharmony_ci * for each face/layer of the attachment bound to current FBO */ 458e5c31af7Sopenharmony_ci gl.useProgram(program_id); 459e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /* first index */, 1 /* n points */); 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error rendering geometry!"); 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci /* Read contents of each layer we rendered to and verify the contents */ 464e5c31af7Sopenharmony_ci for (n_layer = 0; n_layer < m_tests[n_current_test].n_layers; ++n_layer) 465e5c31af7Sopenharmony_ci { 466e5c31af7Sopenharmony_ci const unsigned char* expected_data = 467e5c31af7Sopenharmony_ci m_layered_rendering_expected_layer_data + TEXTURE_N_COMPONENTS * n_layer; 468e5c31af7Sopenharmony_ci unsigned int n = 0; 469e5c31af7Sopenharmony_ci bool texture_layered = false; 470e5c31af7Sopenharmony_ci glw::GLenum texture_target = GL_NONE; 471e5c31af7Sopenharmony_ci 472e5c31af7Sopenharmony_ci /* What is the source attachment's texture target? */ 473e5c31af7Sopenharmony_ci switch (m_tests[n_current_test].iteration) 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci case LAYERED_RENDERING_TEST_ITERATION_CUBEMAP: 476e5c31af7Sopenharmony_ci { 477e5c31af7Sopenharmony_ci texture_layered = false; 478e5c31af7Sopenharmony_ci texture_target = (n_layer == 0) ? 479e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_POSITIVE_X : 480e5c31af7Sopenharmony_ci (n_layer == 1) ? 481e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_NEGATIVE_X : 482e5c31af7Sopenharmony_ci (n_layer == 2) ? GL_TEXTURE_CUBE_MAP_POSITIVE_Y : 483e5c31af7Sopenharmony_ci (n_layer == 3) ? GL_TEXTURE_CUBE_MAP_NEGATIVE_Y : 484e5c31af7Sopenharmony_ci (n_layer == 4) ? GL_TEXTURE_CUBE_MAP_POSITIVE_Z : 485e5c31af7Sopenharmony_ci GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; 486e5c31af7Sopenharmony_ci 487e5c31af7Sopenharmony_ci break; 488e5c31af7Sopenharmony_ci } 489e5c31af7Sopenharmony_ci 490e5c31af7Sopenharmony_ci case LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY: 491e5c31af7Sopenharmony_ci { 492e5c31af7Sopenharmony_ci texture_layered = true; 493e5c31af7Sopenharmony_ci texture_target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES; 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_ci break; 496e5c31af7Sopenharmony_ci } 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci case LAYERED_RENDERING_TEST_ITERATION_3D: 499e5c31af7Sopenharmony_ci { 500e5c31af7Sopenharmony_ci texture_layered = true; 501e5c31af7Sopenharmony_ci texture_target = GL_TEXTURE_3D; 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci break; 504e5c31af7Sopenharmony_ci } 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci case LAYERED_RENDERING_TEST_ITERATION_2D_ARRAY: 507e5c31af7Sopenharmony_ci { 508e5c31af7Sopenharmony_ci texture_layered = true; 509e5c31af7Sopenharmony_ci texture_target = GL_TEXTURE_2D_ARRAY; 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci break; 512e5c31af7Sopenharmony_ci } 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci default: 515e5c31af7Sopenharmony_ci { 516e5c31af7Sopenharmony_ci TCU_FAIL("This location should never be reached"); 517e5c31af7Sopenharmony_ci } 518e5c31af7Sopenharmony_ci } 519e5c31af7Sopenharmony_ci 520e5c31af7Sopenharmony_ci /* Configure the read framebuffer's read buffer, depending on whether the attachment 521e5c31af7Sopenharmony_ci * uses layers or not 522e5c31af7Sopenharmony_ci */ 523e5c31af7Sopenharmony_ci if (texture_layered) 524e5c31af7Sopenharmony_ci { 525e5c31af7Sopenharmony_ci gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_id, 0 /* base mip-map */, 526e5c31af7Sopenharmony_ci n_layer); 527e5c31af7Sopenharmony_ci } 528e5c31af7Sopenharmony_ci else 529e5c31af7Sopenharmony_ci { 530e5c31af7Sopenharmony_ci if (texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_X || 531e5c31af7Sopenharmony_ci texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y || 532e5c31af7Sopenharmony_ci texture_target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z || 533e5c31af7Sopenharmony_ci texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X || 534e5c31af7Sopenharmony_ci texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || 535e5c31af7Sopenharmony_ci texture_target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) 536e5c31af7Sopenharmony_ci { 537e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, texture_id, 538e5c31af7Sopenharmony_ci 0 /* base mip-map */); 539e5c31af7Sopenharmony_ci } 540e5c31af7Sopenharmony_ci else 541e5c31af7Sopenharmony_ci { 542e5c31af7Sopenharmony_ci TCU_FAIL("This location should never be reached"); 543e5c31af7Sopenharmony_ci } 544e5c31af7Sopenharmony_ci } 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ci /* Make sure read framebuffer was configured successfully */ 547e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting read framebuffer!"); 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci /* Read the data */ 550e5c31af7Sopenharmony_ci if (m_tests[n_current_test].iteration == LAYERED_RENDERING_TEST_ITERATION_2D_MULTISAMPLE_ARRAY) 551e5c31af7Sopenharmony_ci { 552e5c31af7Sopenharmony_ci glw::GLuint new_dst_to = 0; 553e5c31af7Sopenharmony_ci glw::GLuint dst_fbo_id = 0; 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &dst_fbo_id); 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_tests[n_current_test].fbo_id); 558e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo_id); 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci gl.genTextures(1, &new_dst_to); 561e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, new_dst_to); 562e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT); 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 565e5c31af7Sopenharmony_ci "Could not setup texture object for draw framebuffer color attachment."); 566e5c31af7Sopenharmony_ci 567e5c31af7Sopenharmony_ci gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, new_dst_to, 0); 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), 570e5c31af7Sopenharmony_ci "Could not attach texture object to draw framebuffer color attachment."); 571e5c31af7Sopenharmony_ci 572e5c31af7Sopenharmony_ci gl.blitFramebuffer(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, 573e5c31af7Sopenharmony_ci GL_COLOR_BUFFER_BIT, GL_LINEAR); 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error blitting from read framebuffer to draw framebuffer."); 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_READ_FRAMEBUFFER, dst_fbo_id); 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 580e5c31af7Sopenharmony_ci 581e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading attachment's data!"); 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_tests[n_current_test].fbo_id); 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &dst_fbo_id); 586e5c31af7Sopenharmony_ci gl.deleteTextures(1, &new_dst_to); 587e5c31af7Sopenharmony_ci } 588e5c31af7Sopenharmony_ci else 589e5c31af7Sopenharmony_ci { 590e5c31af7Sopenharmony_ci gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, buffer); 591e5c31af7Sopenharmony_ci 592e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading attachment's data!"); 593e5c31af7Sopenharmony_ci } 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci /* Validate it */ 596e5c31af7Sopenharmony_ci for (; n < TEXTURE_WIDTH * TEXTURE_HEIGHT; ++n) 597e5c31af7Sopenharmony_ci { 598e5c31af7Sopenharmony_ci unsigned char* data_ptr = buffer + n * TEXTURE_N_COMPONENTS; 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci if (memcmp(data_ptr, expected_data, TEXTURE_N_COMPONENTS) != 0) 601e5c31af7Sopenharmony_ci { 602e5c31af7Sopenharmony_ci m_testCtx.getLog() << tcu::TestLog::Message << "Rendered data [" << data_ptr[0] << ", " 603e5c31af7Sopenharmony_ci << data_ptr[1] << ", " << data_ptr[2] << ", " << data_ptr[3] 604e5c31af7Sopenharmony_ci << "] is different from reference data [" 605e5c31af7Sopenharmony_ci << m_layered_rendering_expected_layer_data[0] << ", " 606e5c31af7Sopenharmony_ci << m_layered_rendering_expected_layer_data[1] << ", " 607e5c31af7Sopenharmony_ci << m_layered_rendering_expected_layer_data[2] << ", " 608e5c31af7Sopenharmony_ci << m_layered_rendering_expected_layer_data[3] << "] !" 609e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 610e5c31af7Sopenharmony_ci 611e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 612e5c31af7Sopenharmony_ci return STOP; 613e5c31af7Sopenharmony_ci } /* if (data comparison failed) */ 614e5c31af7Sopenharmony_ci } /* for (all pixels) */ 615e5c31af7Sopenharmony_ci } /* for (all layers) */ 616e5c31af7Sopenharmony_ci } /* for (all iterations) */ 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci /* Done! */ 619e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 620e5c31af7Sopenharmony_ci return STOP; 621e5c31af7Sopenharmony_ci} 622e5c31af7Sopenharmony_ci 623e5c31af7Sopenharmony_ci/** Deinitializes GLES objects created during the test. 624e5c31af7Sopenharmony_ci * 625e5c31af7Sopenharmony_ci */ 626e5c31af7Sopenharmony_civoid GeometryShaderLayeredRendering::deinit(void) 627e5c31af7Sopenharmony_ci{ 628e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 629e5c31af7Sopenharmony_ci 630e5c31af7Sopenharmony_ci /* Reset OpenGL ES state */ 631e5c31af7Sopenharmony_ci gl.useProgram(0); 632e5c31af7Sopenharmony_ci gl.bindTexture(GL_TEXTURE_2D, 0 /* texture */); 633e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 634e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci for (unsigned int n_current_test = 0; n_current_test < sizeof(m_tests) / sizeof(m_tests[0]); ++n_current_test) 637e5c31af7Sopenharmony_ci { 638e5c31af7Sopenharmony_ci if (m_tests[n_current_test].po_id != 0) 639e5c31af7Sopenharmony_ci { 640e5c31af7Sopenharmony_ci gl.deleteProgram(m_tests[n_current_test].po_id); 641e5c31af7Sopenharmony_ci } 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci if (m_tests[n_current_test].fs_id != 0) 644e5c31af7Sopenharmony_ci { 645e5c31af7Sopenharmony_ci gl.deleteShader(m_tests[n_current_test].fs_id); 646e5c31af7Sopenharmony_ci } 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci if (m_tests[n_current_test].gs_id != 0) 649e5c31af7Sopenharmony_ci { 650e5c31af7Sopenharmony_ci gl.deleteShader(m_tests[n_current_test].gs_id); 651e5c31af7Sopenharmony_ci } 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci if (m_tests[n_current_test].vs_id != 0) 654e5c31af7Sopenharmony_ci { 655e5c31af7Sopenharmony_ci gl.deleteShader(m_tests[n_current_test].vs_id); 656e5c31af7Sopenharmony_ci } 657e5c31af7Sopenharmony_ci 658e5c31af7Sopenharmony_ci if (m_tests[n_current_test].to_id != 0) 659e5c31af7Sopenharmony_ci { 660e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_tests[n_current_test].to_id); 661e5c31af7Sopenharmony_ci } 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci if (m_tests[n_current_test].fbo_id != 0) 664e5c31af7Sopenharmony_ci { 665e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_tests[n_current_test].fbo_id); 666e5c31af7Sopenharmony_ci } 667e5c31af7Sopenharmony_ci } /* for (all tests) */ 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ci if (m_vao_id != 0) 670e5c31af7Sopenharmony_ci { 671e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_vao_id); 672e5c31af7Sopenharmony_ci } 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci /* Release base class */ 675e5c31af7Sopenharmony_ci TestCaseBase::deinit(); 676e5c31af7Sopenharmony_ci} 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci} // namespace glcts 679