Tests for GLES3 number parsing
authorMikko Tiusanen <mikko.tiusanen@siru.fi>
Wed, 4 Nov 2020 08:24:34 +0000 (10:24 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 17 Dec 2020 17:06:26 +0000 (17:06 +0000)
Added tests for number parsing in GLES3.
Includes new tests for unsigned int literals and float parsing tests
imported from Khronos WebGL Conformance Tests.

New tests:

KHR-GLES3.number_parsing.*

Components: OpenGL

VK-GL-CTS issue: 2176

Change-Id: I96c0d14431b5dd5867808319f08c5a614f40d2e0

external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.5.x/gles3-khr-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/3.2.6.x/gles3-khr-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt
external/openglcts/modules/gles3/CMakeLists.txt
external/openglcts/modules/gles3/es3cNumberParsingTests.cpp [new file with mode: 0644]
external/openglcts/modules/gles3/es3cNumberParsingTests.hpp [new file with mode: 0644]
external/openglcts/modules/gles3/es3cTestPackage.cpp

index 836915a..5447d80 100644 (file)
@@ -4267,3 +4267,21 @@ KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_negz
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posx
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posy
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posz
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_max_value_decimal
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base8
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base16
+KHR-GLES3.number_parsing.unsigned_integer_too_large_value_invalid
+KHR-GLES3.number_parsing.unsigned_integer_negative_value_as_uint
+KHR-GLES3.number_parsing.float_out_of_range_as_infinity
+KHR-GLES3.number_parsing.float_out_of_range_as_zero
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_positive_exponent
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_negative_exponent
+KHR-GLES3.number_parsing.float_slightly_out_of_range_exponent_as_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_negative_infinity
index 836915a..5447d80 100644 (file)
@@ -4267,3 +4267,21 @@ KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_negz
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posx
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posy
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posz
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_max_value_decimal
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base8
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base16
+KHR-GLES3.number_parsing.unsigned_integer_too_large_value_invalid
+KHR-GLES3.number_parsing.unsigned_integer_negative_value_as_uint
+KHR-GLES3.number_parsing.float_out_of_range_as_infinity
+KHR-GLES3.number_parsing.float_out_of_range_as_zero
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_positive_exponent
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_negative_exponent
+KHR-GLES3.number_parsing.float_slightly_out_of_range_exponent_as_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_negative_infinity
index 836915a..5447d80 100644 (file)
@@ -4267,3 +4267,21 @@ KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_negz
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posx
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posy
 KHR-GLES3.copy_tex_image_conversions.required.renderbuffer_cubemap_posz
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_decimal
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base8
+KHR-GLES3.number_parsing.unsigned_integer_smallest_value_above_signed_range_base16
+KHR-GLES3.number_parsing.unsigned_integer_max_value_decimal
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base8
+KHR-GLES3.number_parsing.unsigned_integer_max_value_base16
+KHR-GLES3.number_parsing.unsigned_integer_too_large_value_invalid
+KHR-GLES3.number_parsing.unsigned_integer_negative_value_as_uint
+KHR-GLES3.number_parsing.float_out_of_range_as_infinity
+KHR-GLES3.number_parsing.float_out_of_range_as_zero
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_positive_exponent
+KHR-GLES3.number_parsing.float_no_limit_on_number_of_digits_negative_exponent
+KHR-GLES3.number_parsing.float_slightly_out_of_range_exponent_as_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_positive_infinity
+KHR-GLES3.number_parsing.float_overflow_to_negative_infinity
index 0887c5f..7da83b6 100644 (file)
@@ -5,6 +5,8 @@ set(GLCTS_ES3_SRCS
        es3cTestPackage.hpp
        es3cCopyTexImageConversionsTests.cpp
        es3cCopyTexImageConversionsTests.hpp
+       es3cNumberParsingTests.cpp
+       es3cNumberParsingTests.hpp
        )
 
 set(GLCTS_ES3_LIBS
diff --git a/external/openglcts/modules/gles3/es3cNumberParsingTests.cpp b/external/openglcts/modules/gles3/es3cNumberParsingTests.cpp
new file mode 100644 (file)
index 0000000..d0512fb
--- /dev/null
@@ -0,0 +1,492 @@
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2020 Google Inc.
+ * Copyright (c) 2020 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file  es3cNumberParsingTests.cpp
+ * \brief Tests for numeric value parsing in GLSL ES 3.0
+ */ /*-------------------------------------------------------------------*/
+
+#include "es3cNumberParsingTests.hpp"
+
+#include "gluDefs.hpp"
+#include "gluTextureUtil.hpp"
+#include "gluDrawUtil.hpp"
+#include "gluShaderProgram.hpp"
+
+#include "glwDefs.hpp"
+#include "glwFunctions.hpp"
+#include "glwEnums.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuStringTemplate.hpp"
+
+#include <string>
+#include <vector>
+#include <map>
+
+#include <functional>
+
+namespace es3cts
+{
+
+namespace
+{
+using std::string;
+using std::vector;
+using std::map;
+
+using std::function;
+using std::bind;
+using namespace std::placeholders;
+
+static const string                                    defaultVertexShader                                     =
+       "#version 300 es\n"
+       "in vec4 vPosition;\n"
+       "void main()\n"
+       "{\n"
+       "    gl_Position = vPosition;\n"
+       "}\n";
+
+static const string                                    fragmentShaderTemplate                          =
+       "#version 300 es\n"
+       "precision highp float;\n"
+       "out vec4 my_FragColor;\n"
+       "${TEST_GLOBALS}"
+       "void main()\n"
+       "{\n"
+    "${TEST_CODE}"
+    "    my_FragColor = vec4(0.0, correct, 0.0, 1.0);\n"
+       "}\n";
+
+typedef function<void (const glu::ShaderProgram&, const glw::Functions&)> SetupUniformsFn;
+
+enum struct TestType
+{
+       NORMAL                          = 0,
+       EXPECT_SHADER_FAIL
+};
+
+struct TestParams
+{
+       TestType                        testType;
+       string                          name;
+       string                          description;
+       string                          testGlobals;
+       string                          testCode;
+       SetupUniformsFn setupUniformsFn;
+};
+
+static void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value);
+static void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl);
+
+static const TestParams                        tests[]                                                                 =
+{
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_above_signed_range_decimal",                                                                                                                                  // string                       name
+               "Test that uint value higher than INT_MAX is parsed correctly",                                                                                                 // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 3221225472u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 3221225472u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_above_signed_range_base8",                                                                                                                                    // string                       name
+               "Test that uint value higher than INT_MAX is parsed correctly in base 8 (octal)",                                                               // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 030000000000u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 3221225472u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_above_signed_range_base16",                                                                                                                                   // string                       name
+               "Test that uint value higher than INT_MAX is parsed correctly in base 16 (hex)",                                                                // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 0xc0000000u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 3221225472u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_smallest_value_above_signed_range_decimal",                                                                                                   // string                       name
+               "Test that uint value equal to INT_MAX+1 is parsed correctly",                                                                                                  // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 2147483648u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 2147483648u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_smallest_value_above_signed_range_base8",                                                                                                             // string                       name
+               "Test that uint value equal to INT_MAX+1 is parsed correctly in base 8 (octal)",                                                                // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 020000000000u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 2147483648u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_smallest_value_above_signed_range_base16",                                                                                                    // string                       name
+               "Test that uint value equal to INT_MAX+1 is parsed correctly in base 16 (hex)",                                                                 // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 0x80000000u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 2147483648u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_max_value_decimal",                                                                                                                                                   // string                       name
+               "Test that uint value equal to UINT_MAX is parsed correctly",                                                                                                   // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 4294967295u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 4294967295u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_max_value_base8",                                                                                                                                                             // string                       name
+               "Test that uint value equal to UINT_MAX is parsed correctly in base 8 (octal)",                                                                 // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 037777777777u;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 4294967295u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_max_value_base16",                                                                                                                                                    // string                       name
+               "Test that uint value equal to UINT_MAX is parsed correctly in base 16 (hex)",                                                                  // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 0xffffffffu;\n"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 4294967295u)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::EXPECT_SHADER_FAIL,                                                                                                                                                                   // TestType                     testType
+               "unsigned_integer_too_large_value_invalid",                                                                                                                                             // string                       name
+               "Test that uint value outside uint range fails to compile",                                                                                                             // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = 0xfffffffffu;"
+               "    float correct = 0.0;",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "unsigned_integer_negative_value_as_uint",                                                                                                                                              // string                       name
+               "Test that -1u is parsed correctly",                                                                                                                                                    // string                       description
+               "uniform uint expected;\n",                                                                                                                                                                             // string                       testGlobals
+               "    uint i        = -1u;"
+               "    float correct = (i == expected) ? 1.0 : 0.0;\n",
+               bind(initializeExpectedValue, _1, _2, 0xffffffffu)                                                                                                                              // SetupUniformsFn      setupUniformsFn
+       },
+       /* The following floating point parsing tests are taken from the Khronos WebGL conformance tests at:
+        *     https://www.khronos.org/registry/webgl/sdk/tests/conformance2/glsl3/float-parsing.html */
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_out_of_range_as_infinity",                                                                                                                                                               // string                       name
+               "Floats of too large magnitude should be converted infinity",                                                                                                   // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    // Out-of-range floats should overflow to infinity\n"                                                                                                              // string                       testCode
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
+               "    // \"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"
+               "    float correct = isinf(1.0e40) ? 1.0 : 0.0;\n",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_out_of_range_as_zero",                                                                                                                                                                   // string                       name
+               "Floats of too small magnitude should be converted to zero",                                                                                                    // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"                                                                                                                                 // string                       testCode
+               "    // \"A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero.\"\n"
+               "    // 1.0e-50 is small enough that it can't even be stored as subnormal.\n"
+               "    float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;\n",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_no_limit_on_number_of_digits_positive_exponent",                                                                                                                 // string                       name
+               "Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent",                // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"                                                                                                                                 // string                       testCode
+               "    // \"There is no limit on the number of digits in any digit-sequence.\"\n"
+               "    // The below float string has 100 zeros after the decimal point, but represents 1.0.\n"
+               "    float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101;\n"
+               "    float correct = (x == 1.0) ? 1.0 : 0.0;\n",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_no_limit_on_number_of_digits_negative_exponent",                                                                                                                 // string                       name
+               "Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent",             // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"                                                                                                                                 // string                       testCode
+               "    // \"There is no limit on the number of digits in any digit-sequence.\"\n"
+               "    // The below float string has 100 zeros, but represents 1.0.\n"
+               "    float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100;\n"
+               "    float correct = (x == 1.0) ? 1.0 : 0.0;\n",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_slightly_out_of_range_exponent_as_positive_infinity",                                                                                                    // string                       name
+               "Test that an exponent that slightly overflows signed 32-bit int range works",                                                                  // string                       description
+               "",                                                                                                                                                                                                                             // string                       testGlobals
+               "    // Out-of-range floats should overflow to infinity\n"                                                                                                              // string                       testCode
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
+               "    // \"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"
+               "    float correct = isinf(1.0e2147483649) ? 1.0 : 0.0;\n",
+               nullptr                                                                                                                                                                                                                 // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_overflow_to_positive_infinity",                                                                                                                                                  // string                       name
+               "Out-of-range floats greater than zero should overflow to positive infinity",                                                                   // string                       description
+               "uniform float zero;\n",                                                                                                                                                                                // string                       testGlobals
+               "    // Out-of-range floats should overflow to infinity\n"                                                                                                              // string                       testCode
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
+               "    // \"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"
+               "    float f = 1.0e2048 - zero;\n"
+               "    float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0;\n",
+               initializeZeroValue                                                                                                                                                                                             // SetupUniformsFn      setupUniformsFn
+       },
+       {
+               TestType::NORMAL,                                                                                                                                                                                               // TestType                     testType
+               "float_overflow_to_negative_infinity",                                                                                                                                                  // string                       name
+               "Out-of-range floats less than zero should overflow to negative infinity",                                                                              // string                       description
+               "uniform float zero;\n",                                                                                                                                                                                // string                       testGlobals
+               "    // Out-of-range floats should overflow to infinity\n"                                                                                                              // string                       testCode
+               "    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
+               "    // \"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"
+               "    float f = -1.0e2048 + zero;\n"
+               "    float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0;\n",
+               initializeZeroValue                                                                                                                                                                                             // SetupUniformsFn      setupUniformsFn
+       }
+};
+
+static void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value)
+{
+       const auto location = gl.getUniformLocation(program.getProgram(), "expected");
+       GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed");
+
+       gl.uniform1ui(location, value);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed");
+}
+
+static void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl)
+{
+       const auto location = gl.getUniformLocation(program.getProgram(), "zero");
+       GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed");
+
+       gl.uniform1f(location, 0.0f);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed");
+}
+
+static string replacePlaceholders(const string& shaderTemplate, const TestParams& params)
+{
+       map<string,string> fields;
+       fields["TEST_GLOBALS"]  = params.testGlobals;
+       fields["TEST_CODE"]             = params.testCode;
+
+       tcu::StringTemplate output(shaderTemplate);
+       return output.specialize(fields);
+}
+
+static const std::vector<float>                positions                               =
+{
+       -1.0f, -1.0f,
+        1.0f, -1.0f,
+       -1.0f,  1.0f,
+        1.0f,  1.0f
+};
+
+static const std::vector<deUint32>     indices                                 = { 0, 1, 2, 3 };
+
+const deInt32                                          RENDERTARGET_WIDTH              = 16;
+const deInt32                                          RENDERTARGET_HEIGHT             = 16;
+
+class NumberParsingCase : public deqp::TestCase
+{
+public:
+       NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader);
+
+       IterateResult iterate();
+
+private:
+       void setupRenderTarget();
+       void releaseRenderTarget();
+
+       glw::GLuint                     m_fboId;
+       glw::GLuint                     m_rboId;
+
+       const TestParams&       m_params;
+       string                          m_vertexShader;
+       string                          m_fragmentShader;
+};
+
+NumberParsingCase::NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader)
+       : TestCase(context, name.c_str(), params.description.c_str())
+       , m_params(params)
+       , m_vertexShader(vertexShader)
+       , m_fragmentShader(fragmentShader)
+{
+}
+
+NumberParsingCase::IterateResult NumberParsingCase::iterate(void)
+{
+       const auto&     renderContext   = m_context.getRenderContext();
+       const auto&     gl                              = renderContext.getFunctions();
+       const auto      textureFormat   = tcu::TextureFormat(tcu::TextureFormat::RGBA,  tcu::TextureFormat::UNORM_INT8);
+       const auto      transferFormat  = glu::getTransferFormat(textureFormat);
+
+       setupRenderTarget();
+
+       glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
+       if (!program.isOk())
+               switch(m_params.testType)
+               {
+               case TestType::EXPECT_SHADER_FAIL:
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+                       return STOP;
+               default:
+                       TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" + m_fragmentShader);
+                       break;
+               }
+
+       const std::vector<glu::VertexArrayBinding> vertexArrays =
+       {
+               glu::va::Float("vPosition", 2, positions.size(), 0, positions.data()),
+       };
+
+       gl.useProgram(program.getProgram());
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
+
+       if (m_params.setupUniformsFn != DE_NULL)
+               m_params.setupUniformsFn(program, gl);
+
+       gl.clear(GL_COLOR_BUFFER_BIT);
+
+
+       glu::draw(renderContext, program.getProgram(),
+                         static_cast<int>(vertexArrays.size()), vertexArrays.data(),
+                         glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data()));
+
+       const auto                                              pixelSize                               = tcu::getPixelSize(textureFormat);
+       std::vector<deUint8>                    fbData                                  (RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize);
+
+       if (pixelSize < 4)
+               gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
+
+       gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType, fbData.data());
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
+
+       tcu::ConstPixelBufferAccess             fbAccess                                { textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data() };
+       const auto                                              expectedColor                   = tcu::RGBA::green().toVec();
+       bool pass = true;
+       for(int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y)
+               for(int x = 0; x < RENDERTARGET_WIDTH; ++x)
+                       if (fbAccess.getPixel(x,y) != expectedColor)
+                       {
+                               pass = false;
+                               break;
+                       }
+
+       releaseRenderTarget();
+
+       const qpTestResult                              result                                  = (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL);
+       const char*                                             desc                                    = (pass ? "Pass" : "Pixel mismatch; numeric value parsed incorrectly");
+
+       m_testCtx.setTestResult(result, desc);
+
+       return STOP;
+}
+
+void NumberParsingCase::setupRenderTarget()
+{
+       const auto&     renderContext   = m_context.getRenderContext();
+       const auto&     gl                              = renderContext.getFunctions();
+
+       gl.genFramebuffers(1, &m_fboId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
+
+       gl.genRenderbuffers(1, &m_rboId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers");
+
+       gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer");
+
+       gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage");
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer");
+
+       gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer");
+
+       glw::GLenum drawBuffer = GL_COLOR_ATTACHMENT0;
+       gl.drawBuffers(1, &drawBuffer);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");
+
+       glw::GLfloat clearColor[4] = { 0, 0, 0, 0 };
+       gl.clearBufferfv(GL_COLOR, 0, clearColor);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers");
+
+       gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
+}
+
+void NumberParsingCase::releaseRenderTarget()
+{
+       const auto&     renderContext   = m_context.getRenderContext();
+       const auto&     gl                              = renderContext.getFunctions();
+       if (m_fboId != 0)
+       {
+               gl.deleteFramebuffers(1, &m_fboId);
+               m_fboId = 0;
+       }
+       if (m_rboId != 0)
+       {
+               gl.deleteRenderbuffers(1, &m_rboId);
+               m_rboId = 0;
+       }
+}
+
+}
+
+NumberParsingTests::NumberParsingTests(deqp::Context& context)
+       : deqp::TestCaseGroup(context, "number_parsing", "GLSL number parsing tests")
+{
+}
+
+NumberParsingTests::~NumberParsingTests(void)
+{
+}
+
+void NumberParsingTests::init(void)
+{
+       for(const auto& params : tests)
+       {
+               addChild(new NumberParsingCase(m_context, params.name, params, defaultVertexShader, replacePlaceholders(fragmentShaderTemplate, params)));
+       }
+}
+
+}
diff --git a/external/openglcts/modules/gles3/es3cNumberParsingTests.hpp b/external/openglcts/modules/gles3/es3cNumberParsingTests.hpp
new file mode 100644 (file)
index 0000000..d9b9e24
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _ES3CNUMBERPARSINGTESTS_HPP
+#define _ES3CNUMBERPARSINGTESTS_HPP
+
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2020 Google Inc.
+ * Copyright (c) 2020 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file  es3cNumberParsingTests.hpp
+ * \brief Tests for numeric value parsing in GLSL ES 3.0
+ */ /*-------------------------------------------------------------------*/
+
+#include "glcTestCase.hpp"
+
+namespace es3cts
+{
+
+class NumberParsingTests : public deqp::TestCaseGroup
+{
+public:
+       NumberParsingTests(deqp::Context& context);
+       virtual ~NumberParsingTests(void);
+
+       void init(void);
+
+private:
+       NumberParsingTests(const NumberParsingTests& other) = delete;
+       NumberParsingTests& operator=(const NumberParsingTests& other) = delete;
+};
+
+}
+#endif // _ES3CNUMBERPARSINGTESTS_HPP
index 9d07e9c..f62c54a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "es3cTestPackage.hpp"
 #include "es3cCopyTexImageConversionsTests.hpp"
+#include "es3cNumberParsingTests.hpp"
 #include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcExposedExtensionsTests.hpp"
 #include "glcFragDepthTests.hpp"
@@ -189,6 +190,7 @@ void ES30TestPackage::init(void)
                addChild(new glcts::PackedPixelsTests(getContext()));
                addChild(new glcts::PackedDepthStencilTests(getContext()));
                addChild(new es3cts::CopyTexImageConversionsTests(getContext()));
+               addChild(new es3cts::NumberParsingTests(getContext()));
        }
        catch (...)
        {