Test if mediump optimizations are not to aggressive
authorPiotr Byszewski <piotr.byszewski@mobica.com>
Thu, 9 Nov 2017 09:49:25 +0000 (10:49 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 30 Nov 2017 09:28:53 +0000 (04:28 -0500)
GTF sin and cos tests were ported to glcts as they can also
be used to detect overly optimized set of mediump operations.

Components: OpenGL

VK-GL-CTS issue: 706

Affects:
KHR-GL43.aggressive_optimizations.*
KHR-GLES2.shaders.aggressive_optimizations.*
KHR-GLES3.shaders.aggressive_optimizations.*
KHR-GLES31.shaders.aggressive_optimizations.*
KHR-GLES32.shaders.aggressive_optimizations.*

Change-Id: Idd2ea75ea552b9106792775570d64b347db32276

16 files changed:
external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl43-master.txt
external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl44-master.txt
external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl45-master.txt
external/openglcts/data/mustpass/gl/khronos_mustpass/4.6.0.x/gl46-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles2-khr-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles3-khr-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles31-khr-master.txt
external/openglcts/data/mustpass/gles/khronos_mustpass/master/gles32-khr-master.txt
external/openglcts/modules/common/CMakeLists.txt
external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.cpp [new file with mode: 0644]
external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.hpp [new file with mode: 0644]
external/openglcts/modules/gl/gl4cTestPackages.cpp
external/openglcts/modules/gles2/es2cTestPackage.cpp
external/openglcts/modules/gles3/es3cTestPackage.cpp
external/openglcts/modules/gles31/es31cTestPackage.cpp
external/openglcts/modules/gles32/es32cTestPackage.cpp

index ebf7caa..d4bbf52 100644 (file)
@@ -6046,3 +6046,15 @@ KHR-GL43.constant_expressions.array_normalize_vec4_compute
 KHR-GL43.constant_expressions.array_normalize_vec4_geometry
 KHR-GL43.constant_expressions.array_normalize_vec4_tess_control
 KHR-GL43.constant_expressions.array_normalize_vec4_tess_eval
+KHR-GL43.aggressive_optimizations.sin_float_vert
+KHR-GL43.aggressive_optimizations.sin_float_frag
+KHR-GL43.aggressive_optimizations.sin_vec2_vert
+KHR-GL43.aggressive_optimizations.sin_vec2_frag
+KHR-GL43.aggressive_optimizations.sin_vec3_vert
+KHR-GL43.aggressive_optimizations.sin_vec3_frag
+KHR-GL43.aggressive_optimizations.cos_float_vert
+KHR-GL43.aggressive_optimizations.cos_float_frag
+KHR-GL43.aggressive_optimizations.cos_vec2_vert
+KHR-GL43.aggressive_optimizations.cos_vec2_frag
+KHR-GL43.aggressive_optimizations.cos_vec3_vert
+KHR-GL43.aggressive_optimizations.cos_vec3_frag
index 52e5e3b..cf28978 100644 (file)
@@ -6046,6 +6046,18 @@ KHR-GL44.constant_expressions.array_normalize_vec4_compute
 KHR-GL44.constant_expressions.array_normalize_vec4_geometry
 KHR-GL44.constant_expressions.array_normalize_vec4_tess_control
 KHR-GL44.constant_expressions.array_normalize_vec4_tess_eval
+KHR-GL44.aggressive_optimizations.sin_float_vert
+KHR-GL44.aggressive_optimizations.sin_float_frag
+KHR-GL44.aggressive_optimizations.sin_vec2_vert
+KHR-GL44.aggressive_optimizations.sin_vec2_frag
+KHR-GL44.aggressive_optimizations.sin_vec3_vert
+KHR-GL44.aggressive_optimizations.sin_vec3_frag
+KHR-GL44.aggressive_optimizations.cos_float_vert
+KHR-GL44.aggressive_optimizations.cos_float_frag
+KHR-GL44.aggressive_optimizations.cos_vec2_vert
+KHR-GL44.aggressive_optimizations.cos_vec2_frag
+KHR-GL44.aggressive_optimizations.cos_vec3_vert
+KHR-GL44.aggressive_optimizations.cos_vec3_frag
 KHR-GL44.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_vertex
 KHR-GL44.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_fragment
 KHR-GL44.shaders44.preprocessor.line_continuation.comment_vertex
index 59b26dc..797ec67 100644 (file)
@@ -6047,6 +6047,18 @@ KHR-GL45.constant_expressions.array_normalize_vec4_compute
 KHR-GL45.constant_expressions.array_normalize_vec4_geometry
 KHR-GL45.constant_expressions.array_normalize_vec4_tess_control
 KHR-GL45.constant_expressions.array_normalize_vec4_tess_eval
+KHR-GL45.aggressive_optimizations.sin_float_vert
+KHR-GL45.aggressive_optimizations.sin_float_frag
+KHR-GL45.aggressive_optimizations.sin_vec2_vert
+KHR-GL45.aggressive_optimizations.sin_vec2_frag
+KHR-GL45.aggressive_optimizations.sin_vec3_vert
+KHR-GL45.aggressive_optimizations.sin_vec3_frag
+KHR-GL45.aggressive_optimizations.cos_float_vert
+KHR-GL45.aggressive_optimizations.cos_float_frag
+KHR-GL45.aggressive_optimizations.cos_vec2_vert
+KHR-GL45.aggressive_optimizations.cos_vec2_frag
+KHR-GL45.aggressive_optimizations.cos_vec3_vert
+KHR-GL45.aggressive_optimizations.cos_vec3_frag
 KHR-GL45.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_vertex
 KHR-GL45.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_fragment
 KHR-GL45.shaders44.preprocessor.line_continuation.comment_vertex
index c575a98..28c27b1 100644 (file)
@@ -6047,6 +6047,18 @@ KHR-GL46.constant_expressions.array_normalize_vec4_compute
 KHR-GL46.constant_expressions.array_normalize_vec4_geometry
 KHR-GL46.constant_expressions.array_normalize_vec4_tess_control
 KHR-GL46.constant_expressions.array_normalize_vec4_tess_eval
+KHR-GL46.aggressive_optimizations.sin_float_vert
+KHR-GL46.aggressive_optimizations.sin_float_frag
+KHR-GL46.aggressive_optimizations.sin_vec2_vert
+KHR-GL46.aggressive_optimizations.sin_vec2_frag
+KHR-GL46.aggressive_optimizations.sin_vec3_vert
+KHR-GL46.aggressive_optimizations.sin_vec3_frag
+KHR-GL46.aggressive_optimizations.cos_float_vert
+KHR-GL46.aggressive_optimizations.cos_float_frag
+KHR-GL46.aggressive_optimizations.cos_vec2_vert
+KHR-GL46.aggressive_optimizations.cos_vec2_frag
+KHR-GL46.aggressive_optimizations.cos_vec3_vert
+KHR-GL46.aggressive_optimizations.cos_vec3_frag
 KHR-GL46.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_vertex
 KHR-GL46.shaders44.preprocessor.invalid_redefinitions.invalid_identifier_2_fragment
 KHR-GL46.shaders44.preprocessor.line_continuation.comment_vertex
index 446de78..53fcd59 100644 (file)
@@ -1,2 +1,14 @@
 KHR-GLES2.shaders.negative.initialize
 KHR-GLES2.shaders.negative.constant_sequence
+KHR-GLES2.shaders.aggressive_optimizations.sin_float_vert
+KHR-GLES2.shaders.aggressive_optimizations.sin_float_frag
+KHR-GLES2.shaders.aggressive_optimizations.sin_vec2_vert
+KHR-GLES2.shaders.aggressive_optimizations.sin_vec2_frag
+KHR-GLES2.shaders.aggressive_optimizations.sin_vec3_vert
+KHR-GLES2.shaders.aggressive_optimizations.sin_vec3_frag
+KHR-GLES2.shaders.aggressive_optimizations.cos_float_vert
+KHR-GLES2.shaders.aggressive_optimizations.cos_float_frag
+KHR-GLES2.shaders.aggressive_optimizations.cos_vec2_vert
+KHR-GLES2.shaders.aggressive_optimizations.cos_vec2_frag
+KHR-GLES2.shaders.aggressive_optimizations.cos_vec3_vert
+KHR-GLES2.shaders.aggressive_optimizations.cos_vec3_frag
index c1af7e4..dbff5eb 100644 (file)
@@ -2588,6 +2588,18 @@ KHR-GLES3.shaders.shader_integer_mix.mix-uvec4
 KHR-GLES3.shaders.shader_integer_mix.mix-bvec4
 KHR-GLES3.shaders.negative.initialize
 KHR-GLES3.shaders.negative.constant_sequence
+KHR-GLES3.shaders.aggressive_optimizations.sin_float_vert
+KHR-GLES3.shaders.aggressive_optimizations.sin_float_frag
+KHR-GLES3.shaders.aggressive_optimizations.sin_vec2_vert
+KHR-GLES3.shaders.aggressive_optimizations.sin_vec2_frag
+KHR-GLES3.shaders.aggressive_optimizations.sin_vec3_vert
+KHR-GLES3.shaders.aggressive_optimizations.sin_vec3_frag
+KHR-GLES3.shaders.aggressive_optimizations.cos_float_vert
+KHR-GLES3.shaders.aggressive_optimizations.cos_float_frag
+KHR-GLES3.shaders.aggressive_optimizations.cos_vec2_vert
+KHR-GLES3.shaders.aggressive_optimizations.cos_vec2_frag
+KHR-GLES3.shaders.aggressive_optimizations.cos_vec3_vert
+KHR-GLES3.shaders.aggressive_optimizations.cos_vec3_frag
 KHR-GLES3.texture_filter_anisotropic.queries
 KHR-GLES3.texture_filter_anisotropic.drawing
 KHR-GLES3.texture_repeat_mode.r8_49x23_0_clamp_to_edge
index d2e2c87..1d86539 100644 (file)
@@ -2575,3 +2575,15 @@ KHR-GLES31.core.viewport_array.depth_range_depth_test
 KHR-GLES31.core.viewport_array.provoking_vertex
 KHR-GLES31.shaders.negative.initialize
 KHR-GLES31.shaders.negative.constant_sequence
+KHR-GLES31.shaders.aggressive_optimizations.sin_float_vert
+KHR-GLES31.shaders.aggressive_optimizations.sin_float_frag
+KHR-GLES31.shaders.aggressive_optimizations.sin_vec2_vert
+KHR-GLES31.shaders.aggressive_optimizations.sin_vec2_frag
+KHR-GLES31.shaders.aggressive_optimizations.sin_vec3_vert
+KHR-GLES31.shaders.aggressive_optimizations.sin_vec3_frag
+KHR-GLES31.shaders.aggressive_optimizations.cos_float_vert
+KHR-GLES31.shaders.aggressive_optimizations.cos_float_frag
+KHR-GLES31.shaders.aggressive_optimizations.cos_vec2_vert
+KHR-GLES31.shaders.aggressive_optimizations.cos_vec2_frag
+KHR-GLES31.shaders.aggressive_optimizations.cos_vec3_vert
+KHR-GLES31.shaders.aggressive_optimizations.cos_vec3_frag
index 009e2ef..419bfb2 100644 (file)
@@ -15,6 +15,18 @@ KHR-GLES32.shaders.negative.initialize
 KHR-GLES32.shaders.negative.constant_sequence
 KHR-GLES32.shaders.negative.used_uniform_precision_matching
 KHR-GLES32.shaders.negative.unused_uniform_precision_matching
+KHR-GLES32.shaders.aggressive_optimizations.sin_float_vert
+KHR-GLES32.shaders.aggressive_optimizations.sin_float_frag
+KHR-GLES32.shaders.aggressive_optimizations.sin_vec2_vert
+KHR-GLES32.shaders.aggressive_optimizations.sin_vec2_frag
+KHR-GLES32.shaders.aggressive_optimizations.sin_vec3_vert
+KHR-GLES32.shaders.aggressive_optimizations.sin_vec3_frag
+KHR-GLES32.shaders.aggressive_optimizations.cos_float_vert
+KHR-GLES32.shaders.aggressive_optimizations.cos_float_frag
+KHR-GLES32.shaders.aggressive_optimizations.cos_vec2_vert
+KHR-GLES32.shaders.aggressive_optimizations.cos_vec2_frag
+KHR-GLES32.shaders.aggressive_optimizations.cos_vec3_vert
+KHR-GLES32.shaders.aggressive_optimizations.cos_vec3_frag
 KHR-GLES32.core.geometry_shader.adjacency.adjacency_non_indiced_lines
 KHR-GLES32.core.geometry_shader.adjacency.adjacency_indiced_lines
 KHR-GLES32.core.geometry_shader.adjacency.adjacency_non_indiced_line_strip
index 089dc69..eabafb6 100644 (file)
@@ -10,6 +10,8 @@ include_directories(
        )
 
 set(GLCTS_COMMON_SRCS
+       glcAggressiveShaderOptimizationsTests.cpp
+       glcAggressiveShaderOptimizationsTests.hpp
        glcBlendEquationAdvancedTests.cpp
        glcBlendEquationAdvancedTests.hpp
        glcConfigList.hpp
diff --git a/external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.cpp b/external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.cpp
new file mode 100644 (file)
index 0000000..4b4908c
--- /dev/null
@@ -0,0 +1,514 @@
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2017 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  glcAggressiveShaderOptimizationsTests.cpp
+ * \brief Conformance tests that checks if shader optimizations are not
+ *               overly aggressive. This is done by compering result of complex
+ *               trigonometric functions aproximation to shader buil
+ */ /*-------------------------------------------------------------------*/
+
+#include "glcAggressiveShaderOptimizationsTests.hpp"
+#include "deSharedPtr.hpp"
+#include "glsShaderExecUtil.hpp"
+#include "gluContextInfo.hpp"
+#include "gluDrawUtil.hpp"
+#include "gluPixelTransfer.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwFunctions.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuRenderTarget.hpp"
+#include "tcuStringTemplate.hpp"
+#include "tcuSurface.hpp"
+#include "tcuTestLog.hpp"
+
+using namespace glw;
+
+namespace glcts
+{
+
+enum ShaderType
+{
+       TEST_VERTEX_SHADER,
+       TEST_FRAGMENT_SHADER
+};
+
+struct TrigonometryCaseData
+{
+       const char* testedFunction;
+       const char* testedType;
+       const char* colorComponents;
+       ShaderType  shaderType;
+};
+
+class TrigonometryTestCase : public deqp::TestCase
+{
+public:
+       TrigonometryTestCase(deqp::Context& context, const std::string& name, const TrigonometryCaseData& data);
+       virtual ~TrigonometryTestCase();
+
+       IterateResult iterate(void);
+
+protected:
+       glu::ProgramSources prepareSineSources(bool useBuiltin);
+       glu::ProgramSources prepareCosineSources(bool useBuiltin);
+
+       void renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const;
+
+private:
+       ShaderType  m_shaderType;
+       const char* m_testedFunction;
+       std::map<std::string, std::string> m_specializationMap;
+};
+
+TrigonometryTestCase::TrigonometryTestCase(deqp::Context& context, const std::string& name,
+                                                                                  const TrigonometryCaseData& data)
+       : deqp::TestCase(context, name.c_str(), ""), m_shaderType(data.shaderType), m_testedFunction(data.testedFunction)
+{
+       glu::ContextType contextType = m_context.getRenderContext().getType();
+       glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);
+
+       m_specializationMap["VERSION"]                  = glu::getGLSLVersionDeclaration(glslVersion);
+       m_specializationMap["TYPE"]                             = data.testedType;
+       m_specializationMap["COLOR_COMPONENTS"] = data.colorComponents;
+
+       if (glu::contextSupports(contextType, glu::ApiType::es(3, 0)) || glu::isContextTypeGLCore(contextType))
+       {
+               m_specializationMap["IN"]                                               = "in";
+               m_specializationMap["OUT"]                                              = "out";
+               m_specializationMap["ATTRIBUTE"]                                = "in";
+               m_specializationMap["FS_OUT_COLOR_NAME"]                = "fragColor";
+               m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "out vec4 fragColor;";
+       }
+       else
+       {
+               m_specializationMap["IN"]                                               = "varying";
+               m_specializationMap["OUT"]                                              = "varying";
+               m_specializationMap["ATTRIBUTE"]                                = "attribute";
+               m_specializationMap["FS_OUT_COLOR_NAME"]                = "gl_FragColor";
+               m_specializationMap["FS_OUT_COLOR_DECLARATION"] = "";
+       }
+}
+
+TrigonometryTestCase::~TrigonometryTestCase()
+{
+}
+
+glu::ProgramSources TrigonometryTestCase::prepareSineSources(bool useBuiltinSin)
+{
+       const char* vsDefault = "${VERSION}\n"
+                                                       "${ATTRIBUTE} highp vec2 position;\n"
+                                                       "${ATTRIBUTE} highp vec3 baseColor;\n"
+                                                       "${OUT} vec4 color;\n"
+                                                       "void main (void) {\n"
+                                                       "  color = vec4(baseColor, 1.0);\n"
+                                                       "  gl_Position = vec4(position, 0.0, 1.0);\n"
+                                                       "}\n";
+
+       const char* vsCalculateSin = "${VERSION}\n"
+                                                                "${ATTRIBUTE} highp vec2 position;\n"
+                                                                "${ATTRIBUTE} highp vec3 baseColor;\n"
+                                                                "${OUT} vec4 color;\n"
+                                                                "${SIN_FUNCTION_DEFINITION_VS}\n"
+                                                                "void main (void) {\n"
+                                                                "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
+                                                                "  ${TYPE} c = baseColor.${COLOR_COMPONENTS} * M_2PI;\n"
+                                                                "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c);\n"
+                                                                "  \n"
+                                                                "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
+                                                                "  color.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
+                                                                "  gl_Position = vec4(position, 0.0, 1.0);\n"
+                                                                "}\n";
+
+       const char* fsDefault = "${VERSION}\n"
+                                                       "precision mediump float;\n"
+                                                       "${IN} vec4 color;\n"
+                                                       "${FS_OUT_COLOR_DECLARATION}\n"
+                                                       "void main (void) {\n"
+                                                       "  ${FS_OUT_COLOR_NAME} = color;\n"
+                                                       "}\n";
+
+       const char* fsCalculateSin = "${VERSION}\n"
+                                                                "precision mediump float;\n"
+                                                                "${IN} vec4 color;\n"
+                                                                "${FS_OUT_COLOR_DECLARATION}\n\n"
+                                                                "${SIN_FUNCTION_DEFINITION_FS}\n"
+                                                                "void main (void) {\n"
+                                                                "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
+                                                                "  ${TYPE} c = color.${COLOR_COMPONENTS};\n"
+                                                                "  ${TYPE} sin_c = ${SIN_FUNCTION_NAME}(c * M_2PI);\n"
+                                                                "  \n"
+                                                                "  ${FS_OUT_COLOR_NAME} =vec4(0.0, 0.0, 0.0, 1.0);\n"
+                                                                "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = sin_c * 0.5 + 0.5;\n"
+                                                                "}\n";
+
+       std::string vsTemplate;
+       std::string fsTemplate;
+
+       if (m_shaderType == TEST_VERTEX_SHADER)
+       {
+               vsTemplate = vsCalculateSin;
+               fsTemplate = fsDefault;
+       }
+       else
+       {
+               vsTemplate = vsDefault;
+               fsTemplate = fsCalculateSin;
+       }
+
+       if (useBuiltinSin)
+       {
+               m_specializationMap["SIN_FUNCTION_NAME"]                  = "sin";
+               m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] = "";
+               m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] = "";
+       }
+       else
+       {
+               std::string sinFunctionDefinitionVS = "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
+                                                                                         "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
+                                                                                         "  float sign = 1.0;\n"
+                                                                                         "  float fact;\n"
+                                                                                         "  float fact_of;\n"
+                                                                                         "  \n"
+                                                                                         "  // Taylors series expansion for sin \n"
+                                                                                         "  for(int i = 0; i < 12; i++) {\n"
+                                                                                         "    fact = 1.0;\n"
+                                                                                         "    for(int j = 2; j <= 23; j++)\n"
+                                                                                         "      if (j <= 2 * i + 1)\n"
+                                                                                         "        fact *= float(j);\n"
+                                                                                         "    \n"
+                                                                                         "    sin_c += sign * pow(c, ${TYPE}(2.0 * float(i) + 1.0)) / fact;\n"
+                                                                                         "    sign *= -1.0;\n"
+                                                                                         "  }\n"
+                                                                                         "  return sin_c;\n"
+                                                                                         "}";
+               std::string sinFunctionDefinitionFS = "float lerpHelper(float a, float b, float weight) {\n"
+                                                                                         "  return a + (b - a) * weight;\n"
+                                                                                         "}\n"
+                                                                                         "float sinLerpHelper(int index, float weight) {\n"
+                                                                                         "  float sArray[17];\n"
+                                                                                         "  sArray[0] = 0.0;\n"
+                                                                                         "  sArray[1] = 0.382683;\n"
+                                                                                         "  sArray[2] = 0.707107;\n"
+                                                                                         "  sArray[3] = 0.92388;\n"
+                                                                                         "  sArray[4] = 1.0;\n"
+                                                                                         "  sArray[5] = 0.92388;\n"
+                                                                                         "  sArray[6] = 0.707107;\n"
+                                                                                         "  sArray[7] = 0.382683;\n"
+                                                                                         "  sArray[8] = 0.0;\n"
+                                                                                         "  sArray[9] = -0.382683;\n"
+                                                                                         "  sArray[10] = -0.707107;\n"
+                                                                                         "  sArray[11] = -0.92388;\n"
+                                                                                         "  sArray[12] = -1.0;\n"
+                                                                                         "  sArray[13] = -0.923879;\n"
+                                                                                         "  sArray[14] = -0.707107;\n"
+                                                                                         "  sArray[15] = -0.382683;\n"
+                                                                                         "  sArray[16] = 0.0;\n"
+                                                                                         "  \n"
+                                                                                         "  if (index == 0)\n"
+                                                                                         "    return lerpHelper(sArray[0], sArray[1], weight);\n"
+                                                                                         "  if (index == 1)\n"
+                                                                                         "    return lerpHelper(sArray[1], sArray[2], weight);\n"
+                                                                                         "  if (index == 2)\n"
+                                                                                         "    return lerpHelper(sArray[2], sArray[3], weight);\n"
+                                                                                         "  if (index == 3)\n"
+                                                                                         "    return lerpHelper(sArray[3], sArray[4], weight);\n"
+                                                                                         "  if (index == 4)\n"
+                                                                                         "    return lerpHelper(sArray[4], sArray[5], weight);\n"
+                                                                                         "  if (index == 5)\n"
+                                                                                         "    return lerpHelper(sArray[5], sArray[6], weight);\n"
+                                                                                         "  if (index == 6)\n"
+                                                                                         "    return lerpHelper(sArray[6], sArray[7], weight);\n"
+                                                                                         "  if (index == 7)\n"
+                                                                                         "    return lerpHelper(sArray[7], sArray[8], weight);\n"
+                                                                                         "  if (index == 8)\n"
+                                                                                         "    return lerpHelper(sArray[8], sArray[9], weight);\n"
+                                                                                         "  if (index == 9)\n"
+                                                                                         "    return lerpHelper(sArray[9], sArray[10], weight);\n"
+                                                                                         "  if (index == 10)\n"
+                                                                                         "    return lerpHelper(sArray[10], sArray[11], weight);\n"
+                                                                                         "  if (index == 11)\n"
+                                                                                         "    return lerpHelper(sArray[11], sArray[12], weight);\n"
+                                                                                         "  if (index == 12)\n"
+                                                                                         "    return lerpHelper(sArray[12], sArray[13], weight);\n"
+                                                                                         "  if (index == 13)\n"
+                                                                                         "    return lerpHelper(sArray[13], sArray[14], weight);\n"
+                                                                                         "  if (index == 14)\n"
+                                                                                         "    return lerpHelper(sArray[14], sArray[15], weight);\n"
+                                                                                         "  if (index == 15)\n"
+                                                                                         "    return lerpHelper(sArray[15], sArray[16], weight);\n"
+                                                                                         "  return sArray[16];\n"
+                                                                                         "}\n"
+                                                                                         "${TYPE} ${SIN_FUNCTION_NAME}(${TYPE} c) {\n"
+                                                                                         "  ${TYPE} arrVal = c * 2.546478971;\n"
+                                                                                         "  ${TYPE} weight = arrVal - floor(arrVal);\n"
+                                                                                         "  ${TYPE} sin_c = ${TYPE}(0.0);\n"
+                                                                                         "  ${INTERPOLATE_SIN}"
+                                                                                         "  return sin_c;\n"
+                                                                                         "}";
+
+               if (m_specializationMap["TYPE"] == "float")
+               {
+                       m_specializationMap["INTERPOLATE_SIN"] = "\n"
+                                                                                                        "  int index = int(floor(arrVal));\n"
+                                                                                                        "  sin_c = sinLerpHelper(index, weight);\n";
+               }
+               else if (m_specializationMap["TYPE"] == "vec2")
+               {
+                       m_specializationMap["INTERPOLATE_SIN"] = "\n"
+                                                                                                        "  int indexX = int(floor(arrVal.x));\n"
+                                                                                                        "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
+                                                                                                        "  int indexY = int(floor(arrVal.y));\n"
+                                                                                                        "  sin_c.y = sinLerpHelper(indexY, weight.y);\n";
+               }
+               else if (m_specializationMap["TYPE"] == "vec3")
+               {
+                       m_specializationMap["INTERPOLATE_SIN"] = "\n"
+                                                                                                        "  int indexX = int(floor(arrVal.x));\n"
+                                                                                                        "  sin_c.x = sinLerpHelper(indexX, weight.x);\n"
+                                                                                                        "  int indexY = int(floor(arrVal.y));\n"
+                                                                                                        "  sin_c.y = sinLerpHelper(indexY, weight.y);\n"
+                                                                                                        "  int indexZ = int(floor(arrVal.z));\n"
+                                                                                                        "  sin_c.z = sinLerpHelper(indexZ, weight.z);\n";
+               }
+
+               m_specializationMap["SIN_FUNCTION_NAME"] = "calculateSin";
+               m_specializationMap["SIN_FUNCTION_DEFINITION_VS"] =
+                       tcu::StringTemplate(sinFunctionDefinitionVS).specialize(m_specializationMap);
+               m_specializationMap["SIN_FUNCTION_DEFINITION_FS"] =
+                       tcu::StringTemplate(sinFunctionDefinitionFS).specialize(m_specializationMap);
+       }
+
+       // Specialize shader templates
+       vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
+       fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
+       return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
+}
+
+glu::ProgramSources TrigonometryTestCase::prepareCosineSources(bool useBuiltinCos)
+{
+       const char* vsDefault = "${VERSION}\n"
+                                                       "${ATTRIBUTE} highp vec2 position;\n"
+                                                       "${ATTRIBUTE} highp vec3 baseColor;\n"
+                                                       "${OUT} vec4 color;\n"
+                                                       "void main (void) {\n"
+                                                       "  color = vec4(baseColor, 1.0);\n"
+                                                       "  gl_Position = vec4(position, 0.0, 1.0);\n"
+                                                       "}\n";
+
+       const char* vsCalculateCos = "${VERSION}\n"
+                                                                "${ATTRIBUTE} highp vec2 position;\n"
+                                                                "${ATTRIBUTE} highp vec3 baseColor;\n"
+                                                                "${OUT} vec4 color;\n"
+                                                                "${COS_FUNCTION_DEFINITION_VS}\n"
+                                                                "void main (void) {\n"
+                                                                "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
+                                                                "  ${TYPE} c = baseColor.${COLOR_COMPONENTS};\n"
+                                                                "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
+                                                                "  \n"
+                                                                "  color = vec4(0.0, 0.0, 0.0, 1.0);\n"
+                                                                "  color.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
+                                                                "  gl_Position = vec4(position, 0.0, 1.0);\n"
+                                                                "}\n";
+
+       const char* fsDefault = "${VERSION}\n"
+                                                       "precision mediump float;\n"
+                                                       "${IN} vec4 color;\n"
+                                                       "${FS_OUT_COLOR_DECLARATION}\n"
+                                                       "void main (void) {\n"
+                                                       "  ${FS_OUT_COLOR_NAME} = color;\n"
+                                                       "}\n";
+
+       const char* fsCalculateCos = "${VERSION}\n"
+                                                                "precision mediump float;\n"
+                                                                "${IN} vec4 color;\n"
+                                                                "${FS_OUT_COLOR_DECLARATION}\n\n"
+                                                                "// function definitions \n"
+                                                                "${COS_FUNCTION_DEFINITION_FS}\n"
+                                                                "${TYPE} preprocessColor(${TYPE} c) {\n"
+                                                                "  ${PREPROCESS_COLOR};\n"
+                                                                "  return c;\n"
+                                                                "}\n\n"
+                                                                "void main (void) {\n"
+                                                                "  const float M_2PI = 2.0 * 3.14159265358979323846;\n"
+                                                                "  ${TYPE} c = preprocessColor(color.${COLOR_COMPONENTS});\n"
+                                                                "  ${TYPE} cos_c = ${COS_FUNCTION_NAME}(c * M_2PI);\n"
+                                                                "  \n"
+                                                                "  ${FS_OUT_COLOR_NAME} = vec4(0.0, 0.0, 0.0, 1.0);\n"
+                                                                "  ${FS_OUT_COLOR_NAME}.${COLOR_COMPONENTS} = cos_c * 0.5 + 0.5;\n"
+                                                                "}\n";
+
+       std::string vsTemplate;
+       std::string fsTemplate;
+
+       if (m_shaderType == TEST_VERTEX_SHADER)
+       {
+               vsTemplate = vsCalculateCos;
+               fsTemplate = fsDefault;
+       }
+       else
+       {
+               vsTemplate = vsDefault;
+               fsTemplate = fsCalculateCos;
+       }
+
+       if (useBuiltinCos)
+       {
+               m_specializationMap["PREPROCESS_COLOR"]                   = "";
+               m_specializationMap["COS_FUNCTION_NAME"]                  = "cos";
+               m_specializationMap["COS_FUNCTION_DEFINITION_VS"] = "";
+               m_specializationMap["COS_FUNCTION_DEFINITION_FS"] = "";
+       }
+       else
+       {
+               std::string cosFunctionDefinitionVS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
+                                                                                         "  ${TYPE} cos_c = ${TYPE}(1.0);\n"
+                                                                                         "  float sign = -1.0;\n"
+                                                                                         "  float fact =  1.0;\n"
+                                                                                         "  \n"
+                                                                                         "  for(int i = 2; i <= 20; i += 2) {\n"
+                                                                                         "    fact  *= float(i)*float(i-1);\n"
+                                                                                         "    cos_c += sign*pow(c, ${TYPE}(float(i)))/fact;\n"
+                                                                                         "    sign = -sign;\n"
+                                                                                         "  }\n"
+                                                                                         "  return cos_c;\n"
+                                                                                         "}";
+               std::string cosFunctionDefinitionFS = "${TYPE} ${COS_FUNCTION_NAME}(${TYPE} c) {\n"
+                                                                                         "  ${TYPE} cos_c = ${TYPE}(-1.0);\n"
+                                                                                         "  float sign      = 1.0;\n"
+                                                                                         "  float fact_even = 1.0;\n"
+                                                                                         "  float fact_odd  = 1.0;\n"
+                                                                                         "  ${TYPE} sum;\n"
+                                                                                         "  ${TYPE} exp;\n"
+                                                                                         "  \n"
+                                                                                         "  for(int i = 2; i <= 10; i += 2) {\n"
+                                                                                         "    fact_even *= float(i);\n"
+                                                                                         "    fact_odd  *= float(i-1);\n"
+                                                                                         "    exp = ${TYPE}(float(i/2));\n"
+                                                                                         "    sum = sign * pow(abs(c), exp)/fact_even;\n"
+                                                                                         "    cos_c += pow(abs(c), exp)*(sum/fact_odd);\n"
+                                                                                         "    sign = -sign;\n"
+                                                                                         "  }\n"
+                                                                                         "  return cos_c;\n"
+                                                                                         "}";
+
+               m_specializationMap["PREPROCESS_COLOR"]  = "c = (fract(abs(c)) - 0.5)";
+               m_specializationMap["COS_FUNCTION_NAME"] = "calculateCos";
+               m_specializationMap["COS_FUNCTION_DEFINITION_VS"] =
+                       tcu::StringTemplate(cosFunctionDefinitionVS).specialize(m_specializationMap);
+               m_specializationMap["COS_FUNCTION_DEFINITION_FS"] =
+                       tcu::StringTemplate(cosFunctionDefinitionFS).specialize(m_specializationMap);
+       }
+
+       // Specialize shader templates
+       vsTemplate = tcu::StringTemplate(vsTemplate).specialize(m_specializationMap);
+       fsTemplate = tcu::StringTemplate(fsTemplate).specialize(m_specializationMap);
+       return glu::makeVtxFragSources(vsTemplate.c_str(), fsTemplate.c_str());
+}
+
+void TrigonometryTestCase::renderAndGrabSurface(glu::ProgramSources sources, tcu::Surface& result) const
+{
+       static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
+       static const float      positions[]   = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 };
+       static const float      baseColors[]  = { 1.0, 0.0, 0.25, 0.75, 0.25, 1.0, 0.0, 1.0, 0.75, 0.25, 0.5, 0.0 };
+
+       glu::RenderContext&   renderContext = m_context.getRenderContext();
+       const glw::Functions& gl                        = renderContext.getFunctions();
+       glu::ShaderProgram      testProgram(renderContext, sources);
+       if (!testProgram.isOk())
+       {
+               m_testCtx.getLog() << testProgram;
+               TCU_FAIL("Test program compilation failed");
+       }
+
+       // Render
+       gl.useProgram(testProgram.getProgram());
+       const glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, positions),
+                                                                                                        glu::va::Float("baseColor", 3, 4, 0, baseColors) };
+       glu::draw(renderContext, testProgram.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
+                         glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
+
+       // Grab surface
+       glu::readPixels(renderContext, 0, 0, result.getAccess());
+}
+
+tcu::TestNode::IterateResult TrigonometryTestCase::iterate(void)
+{
+       glu::RenderContext&   renderContext = m_context.getRenderContext();
+       const glw::Functions& gl                        = renderContext.getFunctions();
+
+       int  renderWidth  = 64;
+       int  renderHeight = 64;
+       bool isSin                = std::string(m_testedFunction) == "sin";
+
+       gl.viewport(0, 0, renderWidth, renderHeight);
+
+       // Use program that will call trigonometric function aproximation
+       tcu::Surface testSurface(renderWidth, renderHeight);
+       if (isSin)
+               renderAndGrabSurface(prepareSineSources(false), testSurface);
+       else
+               renderAndGrabSurface(prepareCosineSources(false), testSurface);
+
+       // Use reference program that will call builtin function
+       tcu::Surface referenceSurface(renderWidth, renderHeight);
+       if (isSin)
+               renderAndGrabSurface(prepareSineSources(true), referenceSurface);
+       else
+               renderAndGrabSurface(prepareCosineSources(true), referenceSurface);
+
+       // Compare surfaces
+       qpTestResult testResult = QP_TEST_RESULT_FAIL;
+       if (tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", referenceSurface, testSurface, 0.05f,
+                                                 tcu::COMPARE_LOG_RESULT))
+               testResult = QP_TEST_RESULT_PASS;
+
+       m_testCtx.setTestResult(testResult, qpGetTestResultName(testResult));
+       return STOP;
+}
+
+AggressiveShaderOptimizationsTests::AggressiveShaderOptimizationsTests(deqp::Context& context)
+       : TestCaseGroup(context, "aggressive_optimizations", "checks if shader optimizations are not overly aggressive")
+{
+}
+
+AggressiveShaderOptimizationsTests::~AggressiveShaderOptimizationsTests()
+{
+}
+
+void AggressiveShaderOptimizationsTests::init(void)
+{
+       TrigonometryCaseData trigonometryCases[] = {
+               { "sin", "float", "r", TEST_VERTEX_SHADER },  { "sin", "float", "r", TEST_FRAGMENT_SHADER },
+               { "sin", "vec2", "rg", TEST_VERTEX_SHADER },  { "sin", "vec2", "rg", TEST_FRAGMENT_SHADER },
+               { "sin", "vec3", "rgb", TEST_VERTEX_SHADER }, { "sin", "vec3", "rgb", TEST_FRAGMENT_SHADER },
+               { "cos", "float", "r", TEST_VERTEX_SHADER },  { "cos", "float", "r", TEST_FRAGMENT_SHADER },
+               { "cos", "vec2", "rg", TEST_VERTEX_SHADER },  { "cos", "vec2", "rg", TEST_FRAGMENT_SHADER },
+               { "cos", "vec3", "rgb", TEST_VERTEX_SHADER }, { "cos", "vec3", "rgb", TEST_FRAGMENT_SHADER },
+       };
+
+       for (int i = 0; i < DE_LENGTH_OF_ARRAY(trigonometryCases); ++i)
+       {
+               const TrigonometryCaseData& tcd            = trigonometryCases[i];
+               std::string                                     shaderType = (tcd.shaderType == TEST_VERTEX_SHADER) ? "_vert" : "_frag";
+               std::string                                     name       = std::string(tcd.testedFunction) + "_" + tcd.testedType + shaderType;
+               addChild(new TrigonometryTestCase(m_context, name, tcd));
+       }
+}
+
+} // glcts namespace
diff --git a/external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.hpp b/external/openglcts/modules/common/glcAggressiveShaderOptimizationsTests.hpp
new file mode 100644 (file)
index 0000000..9cdfde6
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _GLCAGGRESSIVESHADEROPTIMIZATIONSTESTS_HPP
+#define _GLCAGGRESSIVESHADEROPTIMIZATIONSTESTS_HPP
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2017 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  glcOverlyAggressiveShaderOptimizationTests.hpp
+ * \brief Conformance tests that checks if shader optimizations are not
+ *               overly aggressive.
+ */ /*-----------------------------------------------------------------------------*/
+
+#include "glcTestCase.hpp"
+#include "gluShaderUtil.hpp"
+#include "tcuDefs.hpp"
+
+namespace glcts
+{
+
+class AggressiveShaderOptimizationsTests : public TestCaseGroup
+{
+public:
+       AggressiveShaderOptimizationsTests(deqp::Context& context);
+       ~AggressiveShaderOptimizationsTests();
+
+       void init(void);
+};
+
+} // namespace glcts
+
+#endif // _GLCAGGRESSIVESHADEROPTIMIZATIONSTESTS_HPP
index 60925ad..95ead76 100644 (file)
@@ -68,6 +68,7 @@
 #include "gl4cTextureViewTests.hpp"
 #include "gl4cVertexAttrib64BitTest.hpp"
 #include "gl4cVertexAttribBindingTests.hpp"
+#include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcBlendEquationAdvancedTests.hpp"
 #include "glcExposedExtensionsTests.hpp"
 #include "glcInfoTests.hpp"
@@ -244,6 +245,7 @@ void GL43TestPackage::init(void)
                addChild(new gl4cts::IndirectParametersTests(getContext()));
                addChild(new gl4cts::ShaderBallotTests(getContext()));
                addChild(new glcts::ShaderConstExprTests(getContext()));
+               addChild(new glcts::AggressiveShaderOptimizationsTests(getContext()));
        }
        catch (...)
        {
index 2815364..f7faa91 100644 (file)
@@ -23,6 +23,7 @@
  */ /*-------------------------------------------------------------------*/
 
 #include "es2cTestPackage.hpp"
+#include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcInfoTests.hpp"
 #include "glcShaderNegativeTests.hpp"
 #include "gluRenderContext.hpp"
@@ -116,6 +117,7 @@ public:
        void init(void)
        {
                addChild(new deqp::ShaderNegativeTests(m_context, glu::GLSL_VERSION_100_ES));
+               addChild(new glcts::AggressiveShaderOptimizationsTests(m_context));
        }
 };
 
index 4a0dd51..16a11fc 100644 (file)
@@ -23,6 +23,7 @@
  */ /*-------------------------------------------------------------------*/
 
 #include "es3cTestPackage.hpp"
+#include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcExposedExtensionsTests.hpp"
 #include "glcFragDepthTests.hpp"
 #include "glcInfoTests.hpp"
@@ -140,6 +141,7 @@ public:
                addChild(new deqp::UniformBlockTests(m_context, glu::GLSL_VERSION_300_ES));
                addChild(new deqp::ShaderIntegerMixTests(m_context, glu::GLSL_VERSION_300_ES));
                addChild(new deqp::ShaderNegativeTests(m_context, glu::GLSL_VERSION_300_ES));
+               addChild(new glcts::AggressiveShaderOptimizationsTests(m_context));
        }
 };
 
index 9ac46f3..ef92000 100644 (file)
@@ -42,6 +42,7 @@
 #include "es31cTextureGatherTests.hpp"
 #include "es31cTextureStorageMultisampleTests.hpp"
 #include "es31cVertexAttribBindingTests.hpp"
+#include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcBlendEquationAdvancedTests.hpp"
 #include "glcInfoTests.hpp"
 #include "glcPolygonOffsetClampTests.hpp"
@@ -158,6 +159,7 @@ public:
        void init(void)
        {
                addChild(new deqp::ShaderNegativeTests(m_context, glu::GLSL_VERSION_310_ES));
+               addChild(new glcts::AggressiveShaderOptimizationsTests(m_context));
        }
 };
 
index 32bf289..d6710ae 100644 (file)
@@ -25,6 +25,7 @@
 #include "es32cTestPackage.hpp"
 #include "es32cCopyImageTests.hpp"
 #include "esextcTestPackage.hpp"
+#include "glcAggressiveShaderOptimizationsTests.hpp"
 #include "glcFragDepthTests.hpp"
 #include "glcInfoTests.hpp"
 #include "glcSeparableProgramsTransformFeedbackTests.hpp"
@@ -146,6 +147,7 @@ void ES32TestPackage::init(void)
                tcu::TestCaseGroup* shadersGroup = new tcu::TestCaseGroup(getTestContext(), "shaders", "");
                shadersGroup->addChild(new deqp::ShaderIntegerMixTests(getContext(), glu::GLSL_VERSION_320_ES));
                shadersGroup->addChild(new deqp::ShaderNegativeTests(getContext(), glu::GLSL_VERSION_320_ES));
+               shadersGroup->addChild(new glcts::AggressiveShaderOptimizationsTests(getContext()));
                addChild(shadersGroup);
 
                tcu::TestCaseGroup*  coreGroup = new tcu::TestCaseGroup(getTestContext(), "core", "");