1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2020 Google Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2020 The Khronos Group Inc. 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci */ /*! 21e5c31af7Sopenharmony_ci * \file es3cNumberParsingTests.cpp 22e5c31af7Sopenharmony_ci * \brief Tests for numeric value parsing in GLSL ES 3.0 23e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "es3cNumberParsingTests.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 28e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp" 29e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 30e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 33e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 34e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 37e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 38e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <string> 41e5c31af7Sopenharmony_ci#include <vector> 42e5c31af7Sopenharmony_ci#include <map> 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ci#include <functional> 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_cinamespace es3cts 47e5c31af7Sopenharmony_ci{ 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cinamespace 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ciusing std::string; 52e5c31af7Sopenharmony_ciusing std::vector; 53e5c31af7Sopenharmony_ciusing std::map; 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ciusing std::function; 56e5c31af7Sopenharmony_ciusing std::bind; 57e5c31af7Sopenharmony_ciusing namespace std::placeholders; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cistatic const string defaultVertexShader = 60e5c31af7Sopenharmony_ci "#version 300 es\n" 61e5c31af7Sopenharmony_ci "in vec4 vPosition;\n" 62e5c31af7Sopenharmony_ci "void main()\n" 63e5c31af7Sopenharmony_ci "{\n" 64e5c31af7Sopenharmony_ci " gl_Position = vPosition;\n" 65e5c31af7Sopenharmony_ci "}\n"; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_cistatic const string fragmentShaderTemplate = 68e5c31af7Sopenharmony_ci "#version 300 es\n" 69e5c31af7Sopenharmony_ci "precision highp float;\n" 70e5c31af7Sopenharmony_ci "precision highp int;\n" 71e5c31af7Sopenharmony_ci "out vec4 my_FragColor;\n" 72e5c31af7Sopenharmony_ci "${TEST_GLOBALS}" 73e5c31af7Sopenharmony_ci "void main()\n" 74e5c31af7Sopenharmony_ci "{\n" 75e5c31af7Sopenharmony_ci "${TEST_CODE}" 76e5c31af7Sopenharmony_ci " my_FragColor = vec4(0.0, correct, 0.0, 1.0);\n" 77e5c31af7Sopenharmony_ci "}\n"; 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_citypedef function<void (const glu::ShaderProgram&, const glw::Functions&)> SetupUniformsFn; 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_cienum struct TestType 82e5c31af7Sopenharmony_ci{ 83e5c31af7Sopenharmony_ci NORMAL = 0, 84e5c31af7Sopenharmony_ci EXPECT_SHADER_FAIL 85e5c31af7Sopenharmony_ci}; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_cistruct TestParams 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci TestType testType; 90e5c31af7Sopenharmony_ci string name; 91e5c31af7Sopenharmony_ci string description; 92e5c31af7Sopenharmony_ci string testGlobals; 93e5c31af7Sopenharmony_ci string testCode; 94e5c31af7Sopenharmony_ci SetupUniformsFn setupUniformsFn; 95e5c31af7Sopenharmony_ci}; 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_cistatic void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value); 98e5c31af7Sopenharmony_cistatic void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl); 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_cistatic const TestParams tests[] = 101e5c31af7Sopenharmony_ci{ 102e5c31af7Sopenharmony_ci { 103e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 104e5c31af7Sopenharmony_ci "unsigned_integer_above_signed_range_decimal", // string name 105e5c31af7Sopenharmony_ci "Test that uint value higher than INT_MAX is parsed correctly", // string description 106e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 107e5c31af7Sopenharmony_ci " uint i = 3221225472u;\n" 108e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 109e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 3221225472u) // SetupUniformsFn setupUniformsFn 110e5c31af7Sopenharmony_ci }, 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 113e5c31af7Sopenharmony_ci "unsigned_integer_above_signed_range_base8", // string name 114e5c31af7Sopenharmony_ci "Test that uint value higher than INT_MAX is parsed correctly in base 8 (octal)", // string description 115e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 116e5c31af7Sopenharmony_ci " uint i = 030000000000u;\n" 117e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 118e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 3221225472u) // SetupUniformsFn setupUniformsFn 119e5c31af7Sopenharmony_ci }, 120e5c31af7Sopenharmony_ci { 121e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 122e5c31af7Sopenharmony_ci "unsigned_integer_above_signed_range_base16", // string name 123e5c31af7Sopenharmony_ci "Test that uint value higher than INT_MAX is parsed correctly in base 16 (hex)", // string description 124e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 125e5c31af7Sopenharmony_ci " uint i = 0xc0000000u;\n" 126e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 127e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 3221225472u) // SetupUniformsFn setupUniformsFn 128e5c31af7Sopenharmony_ci }, 129e5c31af7Sopenharmony_ci { 130e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 131e5c31af7Sopenharmony_ci "unsigned_integer_smallest_value_above_signed_range_decimal", // string name 132e5c31af7Sopenharmony_ci "Test that uint value equal to INT_MAX+1 is parsed correctly", // string description 133e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 134e5c31af7Sopenharmony_ci " uint i = 2147483648u;\n" 135e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 136e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 2147483648u) // SetupUniformsFn setupUniformsFn 137e5c31af7Sopenharmony_ci }, 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 140e5c31af7Sopenharmony_ci "unsigned_integer_smallest_value_above_signed_range_base8", // string name 141e5c31af7Sopenharmony_ci "Test that uint value equal to INT_MAX+1 is parsed correctly in base 8 (octal)", // string description 142e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 143e5c31af7Sopenharmony_ci " uint i = 020000000000u;\n" 144e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 145e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 2147483648u) // SetupUniformsFn setupUniformsFn 146e5c31af7Sopenharmony_ci }, 147e5c31af7Sopenharmony_ci { 148e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 149e5c31af7Sopenharmony_ci "unsigned_integer_smallest_value_above_signed_range_base16", // string name 150e5c31af7Sopenharmony_ci "Test that uint value equal to INT_MAX+1 is parsed correctly in base 16 (hex)", // string description 151e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 152e5c31af7Sopenharmony_ci " uint i = 0x80000000u;\n" 153e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 154e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 2147483648u) // SetupUniformsFn setupUniformsFn 155e5c31af7Sopenharmony_ci }, 156e5c31af7Sopenharmony_ci { 157e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 158e5c31af7Sopenharmony_ci "unsigned_integer_max_value_decimal", // string name 159e5c31af7Sopenharmony_ci "Test that uint value equal to UINT_MAX is parsed correctly", // string description 160e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 161e5c31af7Sopenharmony_ci " uint i = 4294967295u;\n" 162e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 163e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 4294967295u) // SetupUniformsFn setupUniformsFn 164e5c31af7Sopenharmony_ci }, 165e5c31af7Sopenharmony_ci { 166e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 167e5c31af7Sopenharmony_ci "unsigned_integer_max_value_base8", // string name 168e5c31af7Sopenharmony_ci "Test that uint value equal to UINT_MAX is parsed correctly in base 8 (octal)", // string description 169e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 170e5c31af7Sopenharmony_ci " uint i = 037777777777u;\n" 171e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 172e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 4294967295u) // SetupUniformsFn setupUniformsFn 173e5c31af7Sopenharmony_ci }, 174e5c31af7Sopenharmony_ci { 175e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 176e5c31af7Sopenharmony_ci "unsigned_integer_max_value_base16", // string name 177e5c31af7Sopenharmony_ci "Test that uint value equal to UINT_MAX is parsed correctly in base 16 (hex)", // string description 178e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 179e5c31af7Sopenharmony_ci " uint i = 0xffffffffu;\n" 180e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 181e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 4294967295u) // SetupUniformsFn setupUniformsFn 182e5c31af7Sopenharmony_ci }, 183e5c31af7Sopenharmony_ci { 184e5c31af7Sopenharmony_ci TestType::EXPECT_SHADER_FAIL, // TestType testType 185e5c31af7Sopenharmony_ci "unsigned_integer_too_large_value_invalid", // string name 186e5c31af7Sopenharmony_ci "Test that uint value outside uint range fails to compile", // string description 187e5c31af7Sopenharmony_ci "", // string testGlobals 188e5c31af7Sopenharmony_ci " uint i = 0xfffffffffu;" 189e5c31af7Sopenharmony_ci " float correct = 0.0;", 190e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 191e5c31af7Sopenharmony_ci }, 192e5c31af7Sopenharmony_ci { 193e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 194e5c31af7Sopenharmony_ci "unsigned_integer_negative_value_as_uint", // string name 195e5c31af7Sopenharmony_ci "Test that -1u is parsed correctly", // string description 196e5c31af7Sopenharmony_ci "uniform uint expected;\n", // string testGlobals 197e5c31af7Sopenharmony_ci " uint i = -1u;" 198e5c31af7Sopenharmony_ci " float correct = (i == expected) ? 1.0 : 0.0;\n", 199e5c31af7Sopenharmony_ci bind(initializeExpectedValue, _1, _2, 0xffffffffu) // SetupUniformsFn setupUniformsFn 200e5c31af7Sopenharmony_ci }, 201e5c31af7Sopenharmony_ci /* The following floating point parsing tests are taken from the Khronos WebGL conformance tests at: 202e5c31af7Sopenharmony_ci * https://www.khronos.org/registry/webgl/sdk/tests/conformance2/glsl3/float-parsing.html */ 203e5c31af7Sopenharmony_ci { 204e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 205e5c31af7Sopenharmony_ci "float_out_of_range_as_infinity", // string name 206e5c31af7Sopenharmony_ci "Floats of too large magnitude should be converted infinity", // string description 207e5c31af7Sopenharmony_ci "", // string testGlobals 208e5c31af7Sopenharmony_ci " // Out-of-range floats should overflow to infinity\n" // string testCode 209e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" 210e5c31af7Sopenharmony_ci " // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n" 211e5c31af7Sopenharmony_ci " float correct = isinf(1.0e40) ? 1.0 : 0.0;\n", 212e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 213e5c31af7Sopenharmony_ci }, 214e5c31af7Sopenharmony_ci { 215e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 216e5c31af7Sopenharmony_ci "float_out_of_range_as_zero", // string name 217e5c31af7Sopenharmony_ci "Floats of too small magnitude should be converted to zero", // string description 218e5c31af7Sopenharmony_ci "", // string testGlobals 219e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" // string testCode 220e5c31af7Sopenharmony_ci " // \"A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero.\"\n" 221e5c31af7Sopenharmony_ci " // 1.0e-50 is small enough that it can't even be stored as subnormal.\n" 222e5c31af7Sopenharmony_ci " float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;\n", 223e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 224e5c31af7Sopenharmony_ci }, 225e5c31af7Sopenharmony_ci { 226e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 227e5c31af7Sopenharmony_ci "float_no_limit_on_number_of_digits_positive_exponent", // string name 228e5c31af7Sopenharmony_ci "Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent", // string description 229e5c31af7Sopenharmony_ci "", // string testGlobals 230e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" // string testCode 231e5c31af7Sopenharmony_ci " // \"There is no limit on the number of digits in any digit-sequence.\"\n" 232e5c31af7Sopenharmony_ci " // The below float string has 100 zeros after the decimal point, but represents 1.0.\n" 233e5c31af7Sopenharmony_ci " float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101;\n" 234e5c31af7Sopenharmony_ci " float correct = (x == 1.0) ? 1.0 : 0.0;\n", 235e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 236e5c31af7Sopenharmony_ci }, 237e5c31af7Sopenharmony_ci { 238e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 239e5c31af7Sopenharmony_ci "float_no_limit_on_number_of_digits_negative_exponent", // string name 240e5c31af7Sopenharmony_ci "Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent", // string description 241e5c31af7Sopenharmony_ci "", // string testGlobals 242e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" // string testCode 243e5c31af7Sopenharmony_ci " // \"There is no limit on the number of digits in any digit-sequence.\"\n" 244e5c31af7Sopenharmony_ci " // The below float string has 100 zeros, but represents 1.0.\n" 245e5c31af7Sopenharmony_ci " float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100;\n" 246e5c31af7Sopenharmony_ci " float correct = (x == 1.0) ? 1.0 : 0.0;\n", 247e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 248e5c31af7Sopenharmony_ci }, 249e5c31af7Sopenharmony_ci { 250e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 251e5c31af7Sopenharmony_ci "float_slightly_out_of_range_exponent_as_positive_infinity", // string name 252e5c31af7Sopenharmony_ci "Test that an exponent that slightly overflows signed 32-bit int range works", // string description 253e5c31af7Sopenharmony_ci "", // string testGlobals 254e5c31af7Sopenharmony_ci " // Out-of-range floats should overflow to infinity\n" // string testCode 255e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" 256e5c31af7Sopenharmony_ci " // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n" 257e5c31af7Sopenharmony_ci " float correct = isinf(1.0e2147483649) ? 1.0 : 0.0;\n", 258e5c31af7Sopenharmony_ci nullptr // SetupUniformsFn setupUniformsFn 259e5c31af7Sopenharmony_ci }, 260e5c31af7Sopenharmony_ci { 261e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 262e5c31af7Sopenharmony_ci "float_overflow_to_positive_infinity", // string name 263e5c31af7Sopenharmony_ci "Out-of-range floats greater than zero should overflow to positive infinity", // string description 264e5c31af7Sopenharmony_ci "uniform float zero;\n", // string testGlobals 265e5c31af7Sopenharmony_ci " // Out-of-range floats should overflow to infinity\n" // string testCode 266e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" 267e5c31af7Sopenharmony_ci " // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n" 268e5c31af7Sopenharmony_ci " float f = 1.0e2048 - zero;\n" 269e5c31af7Sopenharmony_ci " float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0;\n", 270e5c31af7Sopenharmony_ci initializeZeroValue // SetupUniformsFn setupUniformsFn 271e5c31af7Sopenharmony_ci }, 272e5c31af7Sopenharmony_ci { 273e5c31af7Sopenharmony_ci TestType::NORMAL, // TestType testType 274e5c31af7Sopenharmony_ci "float_overflow_to_negative_infinity", // string name 275e5c31af7Sopenharmony_ci "Out-of-range floats less than zero should overflow to negative infinity", // string description 276e5c31af7Sopenharmony_ci "uniform float zero;\n", // string testGlobals 277e5c31af7Sopenharmony_ci " // Out-of-range floats should overflow to infinity\n" // string testCode 278e5c31af7Sopenharmony_ci " // GLSL ES 3.00.6 section 4.1.4 Floats:\n" 279e5c31af7Sopenharmony_ci " // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n" 280e5c31af7Sopenharmony_ci " float f = -1.0e2048 + zero;\n" 281e5c31af7Sopenharmony_ci " float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0;\n", 282e5c31af7Sopenharmony_ci initializeZeroValue // SetupUniformsFn setupUniformsFn 283e5c31af7Sopenharmony_ci } 284e5c31af7Sopenharmony_ci}; 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_cistatic void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value) 287e5c31af7Sopenharmony_ci{ 288e5c31af7Sopenharmony_ci const auto location = gl.getUniformLocation(program.getProgram(), "expected"); 289e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed"); 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci gl.uniform1ui(location, value); 292e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed"); 293e5c31af7Sopenharmony_ci} 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_cistatic void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl) 296e5c31af7Sopenharmony_ci{ 297e5c31af7Sopenharmony_ci const auto location = gl.getUniformLocation(program.getProgram(), "zero"); 298e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed"); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci gl.uniform1f(location, 0.0f); 301e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed"); 302e5c31af7Sopenharmony_ci} 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_cistatic string replacePlaceholders(const string& shaderTemplate, const TestParams& params) 305e5c31af7Sopenharmony_ci{ 306e5c31af7Sopenharmony_ci map<string,string> fields; 307e5c31af7Sopenharmony_ci fields["TEST_GLOBALS"] = params.testGlobals; 308e5c31af7Sopenharmony_ci fields["TEST_CODE"] = params.testCode; 309e5c31af7Sopenharmony_ci 310e5c31af7Sopenharmony_ci tcu::StringTemplate output(shaderTemplate); 311e5c31af7Sopenharmony_ci return output.specialize(fields); 312e5c31af7Sopenharmony_ci} 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_cistatic const std::vector<float> positions = 315e5c31af7Sopenharmony_ci{ 316e5c31af7Sopenharmony_ci -1.0f, -1.0f, 317e5c31af7Sopenharmony_ci 1.0f, -1.0f, 318e5c31af7Sopenharmony_ci -1.0f, 1.0f, 319e5c31af7Sopenharmony_ci 1.0f, 1.0f 320e5c31af7Sopenharmony_ci}; 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_cistatic const std::vector<deUint32> indices = { 0, 1, 2, 3 }; 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ciconst deInt32 RENDERTARGET_WIDTH = 16; 325e5c31af7Sopenharmony_ciconst deInt32 RENDERTARGET_HEIGHT = 16; 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ciclass NumberParsingCase : public deqp::TestCase 328e5c31af7Sopenharmony_ci{ 329e5c31af7Sopenharmony_cipublic: 330e5c31af7Sopenharmony_ci NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader); 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci IterateResult iterate(); 333e5c31af7Sopenharmony_ci 334e5c31af7Sopenharmony_ciprivate: 335e5c31af7Sopenharmony_ci void setupRenderTarget(); 336e5c31af7Sopenharmony_ci void releaseRenderTarget(); 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci glw::GLuint m_fboId; 339e5c31af7Sopenharmony_ci glw::GLuint m_rboId; 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci const TestParams& m_params; 342e5c31af7Sopenharmony_ci string m_vertexShader; 343e5c31af7Sopenharmony_ci string m_fragmentShader; 344e5c31af7Sopenharmony_ci}; 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ciNumberParsingCase::NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader) 347e5c31af7Sopenharmony_ci : TestCase(context, name.c_str(), params.description.c_str()) 348e5c31af7Sopenharmony_ci , m_fboId(0) 349e5c31af7Sopenharmony_ci , m_rboId(0) 350e5c31af7Sopenharmony_ci , m_params(params) 351e5c31af7Sopenharmony_ci , m_vertexShader(vertexShader) 352e5c31af7Sopenharmony_ci , m_fragmentShader(fragmentShader) 353e5c31af7Sopenharmony_ci{ 354e5c31af7Sopenharmony_ci} 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ciNumberParsingCase::IterateResult NumberParsingCase::iterate(void) 357e5c31af7Sopenharmony_ci{ 358e5c31af7Sopenharmony_ci const auto& renderContext = m_context.getRenderContext(); 359e5c31af7Sopenharmony_ci const auto& gl = renderContext.getFunctions(); 360e5c31af7Sopenharmony_ci const auto textureFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); 361e5c31af7Sopenharmony_ci const auto transferFormat = glu::getTransferFormat(textureFormat); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci setupRenderTarget(); 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader)); 366e5c31af7Sopenharmony_ci if (!program.isOk()) 367e5c31af7Sopenharmony_ci switch(m_params.testType) 368e5c31af7Sopenharmony_ci { 369e5c31af7Sopenharmony_ci case TestType::EXPECT_SHADER_FAIL: 370e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 371e5c31af7Sopenharmony_ci return STOP; 372e5c31af7Sopenharmony_ci default: 373e5c31af7Sopenharmony_ci TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" + m_fragmentShader); 374e5c31af7Sopenharmony_ci } 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci const std::vector<glu::VertexArrayBinding> vertexArrays = 377e5c31af7Sopenharmony_ci { 378e5c31af7Sopenharmony_ci glu::va::Float("vPosition", 2, positions.size(), 0, positions.data()), 379e5c31af7Sopenharmony_ci }; 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci gl.useProgram(program.getProgram()); 382e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed"); 383e5c31af7Sopenharmony_ci 384e5c31af7Sopenharmony_ci if (m_params.setupUniformsFn != DE_NULL) 385e5c31af7Sopenharmony_ci m_params.setupUniformsFn(program, gl); 386e5c31af7Sopenharmony_ci 387e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci glu::draw(renderContext, program.getProgram(), 391e5c31af7Sopenharmony_ci static_cast<int>(vertexArrays.size()), vertexArrays.data(), 392e5c31af7Sopenharmony_ci glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data())); 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci const auto pixelSize = tcu::getPixelSize(textureFormat); 395e5c31af7Sopenharmony_ci std::vector<deUint8> fbData (RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci if (pixelSize < 4) 398e5c31af7Sopenharmony_ci gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType, fbData.data()); 401e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); 402e5c31af7Sopenharmony_ci 403e5c31af7Sopenharmony_ci tcu::ConstPixelBufferAccess fbAccess { textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data() }; 404e5c31af7Sopenharmony_ci const auto expectedColor = tcu::RGBA::green().toVec(); 405e5c31af7Sopenharmony_ci bool pass = true; 406e5c31af7Sopenharmony_ci for(int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y) 407e5c31af7Sopenharmony_ci for(int x = 0; x < RENDERTARGET_WIDTH; ++x) 408e5c31af7Sopenharmony_ci if (fbAccess.getPixel(x,y) != expectedColor) 409e5c31af7Sopenharmony_ci { 410e5c31af7Sopenharmony_ci pass = false; 411e5c31af7Sopenharmony_ci break; 412e5c31af7Sopenharmony_ci } 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci releaseRenderTarget(); 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci const qpTestResult result = (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL); 417e5c31af7Sopenharmony_ci const char* desc = (pass ? "Pass" : "Pixel mismatch; numeric value parsed incorrectly"); 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci m_testCtx.setTestResult(result, desc); 420e5c31af7Sopenharmony_ci 421e5c31af7Sopenharmony_ci return STOP; 422e5c31af7Sopenharmony_ci} 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_civoid NumberParsingCase::setupRenderTarget() 425e5c31af7Sopenharmony_ci{ 426e5c31af7Sopenharmony_ci const auto& renderContext = m_context.getRenderContext(); 427e5c31af7Sopenharmony_ci const auto& gl = renderContext.getFunctions(); 428e5c31af7Sopenharmony_ci 429e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &m_fboId); 430e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci gl.genRenderbuffers(1, &m_rboId); 433e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers"); 434e5c31af7Sopenharmony_ci 435e5c31af7Sopenharmony_ci gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId); 436e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer"); 437e5c31af7Sopenharmony_ci 438e5c31af7Sopenharmony_ci gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT); 439e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage"); 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId); 442e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer"); 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId); 445e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer"); 446e5c31af7Sopenharmony_ci 447e5c31af7Sopenharmony_ci glw::GLenum drawBuffer = GL_COLOR_ATTACHMENT0; 448e5c31af7Sopenharmony_ci gl.drawBuffers(1, &drawBuffer); 449e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers"); 450e5c31af7Sopenharmony_ci 451e5c31af7Sopenharmony_ci glw::GLfloat clearColor[4] = { 0, 0, 0, 0 }; 452e5c31af7Sopenharmony_ci gl.clearBufferfv(GL_COLOR, 0, clearColor); 453e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers"); 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT); 456e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 457e5c31af7Sopenharmony_ci} 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_civoid NumberParsingCase::releaseRenderTarget() 460e5c31af7Sopenharmony_ci{ 461e5c31af7Sopenharmony_ci const auto& renderContext = m_context.getRenderContext(); 462e5c31af7Sopenharmony_ci const auto& gl = renderContext.getFunctions(); 463e5c31af7Sopenharmony_ci if (m_fboId != 0) 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_fboId); 466e5c31af7Sopenharmony_ci m_fboId = 0; 467e5c31af7Sopenharmony_ci } 468e5c31af7Sopenharmony_ci if (m_rboId != 0) 469e5c31af7Sopenharmony_ci { 470e5c31af7Sopenharmony_ci gl.deleteRenderbuffers(1, &m_rboId); 471e5c31af7Sopenharmony_ci m_rboId = 0; 472e5c31af7Sopenharmony_ci } 473e5c31af7Sopenharmony_ci} 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci} 476e5c31af7Sopenharmony_ci 477e5c31af7Sopenharmony_ciNumberParsingTests::NumberParsingTests(deqp::Context& context) 478e5c31af7Sopenharmony_ci : deqp::TestCaseGroup(context, "number_parsing", "GLSL number parsing tests") 479e5c31af7Sopenharmony_ci{ 480e5c31af7Sopenharmony_ci} 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ciNumberParsingTests::~NumberParsingTests(void) 483e5c31af7Sopenharmony_ci{ 484e5c31af7Sopenharmony_ci} 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_civoid NumberParsingTests::init(void) 487e5c31af7Sopenharmony_ci{ 488e5c31af7Sopenharmony_ci for(const auto& params : tests) 489e5c31af7Sopenharmony_ci { 490e5c31af7Sopenharmony_ci addChild(new NumberParsingCase(m_context, params.name, params, defaultVertexShader, replacePlaceholders(fragmentShaderTemplate, params))); 491e5c31af7Sopenharmony_ci } 492e5c31af7Sopenharmony_ci} 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci} 495