1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 2.0 Module 3e5c31af7Sopenharmony_ci * ------------------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Algorithm implementation tests. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "es2fShaderAlgorithmTests.hpp" 25e5c31af7Sopenharmony_ci#include "glsShaderRenderCase.hpp" 26e5c31af7Sopenharmony_ci#include "gluShaderUtil.hpp" 27e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include "deInt32.h" 30e5c31af7Sopenharmony_ci#include "deMemory.h" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include <map> 33e5c31af7Sopenharmony_ci#include <algorithm> 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ciusing namespace std; 36e5c31af7Sopenharmony_ciusing namespace tcu; 37e5c31af7Sopenharmony_ciusing namespace glu; 38e5c31af7Sopenharmony_ciusing namespace deqp::gls; 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_cinamespace deqp 41e5c31af7Sopenharmony_ci{ 42e5c31af7Sopenharmony_cinamespace gles2 43e5c31af7Sopenharmony_ci{ 44e5c31af7Sopenharmony_cinamespace Functional 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci// ShaderAlgorithmCase 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciclass ShaderAlgorithmCase : public ShaderRenderCase 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_cipublic: 52e5c31af7Sopenharmony_ci ShaderAlgorithmCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource); 53e5c31af7Sopenharmony_ci virtual ~ShaderAlgorithmCase (void); 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ciprivate: 56e5c31af7Sopenharmony_ci ShaderAlgorithmCase (const ShaderAlgorithmCase&); // not allowed! 57e5c31af7Sopenharmony_ci ShaderAlgorithmCase& operator= (const ShaderAlgorithmCase&); // not allowed! 58e5c31af7Sopenharmony_ci}; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ciShaderAlgorithmCase::ShaderAlgorithmCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource) 61e5c31af7Sopenharmony_ci : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc) 62e5c31af7Sopenharmony_ci{ 63e5c31af7Sopenharmony_ci m_vertShaderSource = vertShaderSource; 64e5c31af7Sopenharmony_ci m_fragShaderSource = fragShaderSource; 65e5c31af7Sopenharmony_ci} 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ciShaderAlgorithmCase::~ShaderAlgorithmCase (void) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci} 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci// Helpers. 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_cistatic ShaderAlgorithmCase* createExpressionCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LineStream& shaderBody) 74e5c31af7Sopenharmony_ci{ 75e5c31af7Sopenharmony_ci std::ostringstream vtx; 76e5c31af7Sopenharmony_ci std::ostringstream frag; 77e5c31af7Sopenharmony_ci std::ostringstream& op = isVertexCase ? vtx : frag; 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci vtx << "attribute highp vec4 a_position;\n"; 80e5c31af7Sopenharmony_ci vtx << "attribute highp vec4 a_unitCoords;\n"; 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ci if (isVertexCase) 83e5c31af7Sopenharmony_ci { 84e5c31af7Sopenharmony_ci vtx << "varying mediump vec3 v_color;\n"; 85e5c31af7Sopenharmony_ci frag << "varying mediump vec3 v_color;\n"; 86e5c31af7Sopenharmony_ci } 87e5c31af7Sopenharmony_ci else 88e5c31af7Sopenharmony_ci { 89e5c31af7Sopenharmony_ci vtx << "varying mediump vec4 v_coords;\n"; 90e5c31af7Sopenharmony_ci frag << "varying mediump vec4 v_coords;\n"; 91e5c31af7Sopenharmony_ci } 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci// op << "uniform mediump sampler2D ut_brick;\n"; 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci vtx << "\n"; 96e5c31af7Sopenharmony_ci vtx << "void main()\n"; 97e5c31af7Sopenharmony_ci vtx << "{\n"; 98e5c31af7Sopenharmony_ci vtx << " gl_Position = a_position;\n"; 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci frag << "\n"; 101e5c31af7Sopenharmony_ci frag << "void main()\n"; 102e5c31af7Sopenharmony_ci frag << "{\n"; 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_ci // Write matrix. 105e5c31af7Sopenharmony_ci if (isVertexCase) 106e5c31af7Sopenharmony_ci op << " ${PRECISION} vec4 coords = a_unitCoords;\n"; 107e5c31af7Sopenharmony_ci else 108e5c31af7Sopenharmony_ci op << " ${PRECISION} vec4 coords = v_coords;\n"; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci op << " ${PRECISION} vec3 res = vec3(0.0);\n"; 111e5c31af7Sopenharmony_ci op << shaderBody.str(); 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci if (isVertexCase) 114e5c31af7Sopenharmony_ci { 115e5c31af7Sopenharmony_ci vtx << " v_color = res;\n"; 116e5c31af7Sopenharmony_ci frag << " gl_FragColor = vec4(v_color, 1.0);\n"; 117e5c31af7Sopenharmony_ci } 118e5c31af7Sopenharmony_ci else 119e5c31af7Sopenharmony_ci { 120e5c31af7Sopenharmony_ci vtx << " v_coords = a_unitCoords;\n"; 121e5c31af7Sopenharmony_ci frag << " gl_FragColor = vec4(res, 1.0);\n"; 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci vtx << "}\n"; 125e5c31af7Sopenharmony_ci frag << "}\n"; 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci // Fill in shader templates. 128e5c31af7Sopenharmony_ci map<string, string> params; 129e5c31af7Sopenharmony_ci params.insert(pair<string, string>("PRECISION", "mediump")); 130e5c31af7Sopenharmony_ci 131e5c31af7Sopenharmony_ci StringTemplate vertTemplate(vtx.str().c_str()); 132e5c31af7Sopenharmony_ci StringTemplate fragTemplate(frag.str().c_str()); 133e5c31af7Sopenharmony_ci string vertexShaderSource = vertTemplate.specialize(params); 134e5c31af7Sopenharmony_ci string fragmentShaderSource = fragTemplate.specialize(params); 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci return new ShaderAlgorithmCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str()); 137e5c31af7Sopenharmony_ci} 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci// ShaderAlgorithmTests. 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ciShaderAlgorithmTests::ShaderAlgorithmTests(Context& context) 142e5c31af7Sopenharmony_ci : TestCaseGroup(context, "algorithm", "Miscellaneous algorithm implementations using shaders.") 143e5c31af7Sopenharmony_ci{ 144e5c31af7Sopenharmony_ci} 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ciShaderAlgorithmTests::~ShaderAlgorithmTests (void) 147e5c31af7Sopenharmony_ci{ 148e5c31af7Sopenharmony_ci} 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_civoid ShaderAlgorithmTests::init (void) 151e5c31af7Sopenharmony_ci{ 152e5c31af7Sopenharmony_ci// TestCaseGroup* colorGroup = new TestCaseGroup(m_testCtx, "color", "Miscellaneous color related algorithm tests."); 153e5c31af7Sopenharmony_ci// addChild(colorGroup); 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci #define SHADER_OP_CASE(NAME, DESCRIPTION, SHADER_OP, EVAL_FUNC_BODY) \ 156e5c31af7Sopenharmony_ci do { \ 157e5c31af7Sopenharmony_ci struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ 158e5c31af7Sopenharmony_ci addChild(createExpressionCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, SHADER_OP)); \ 159e5c31af7Sopenharmony_ci addChild(createExpressionCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, SHADER_OP)); \ 160e5c31af7Sopenharmony_ci } while (deGetFalse()) 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci SHADER_OP_CASE(hsl_to_rgb, "Conversion from HSL color space into RGB.", 163e5c31af7Sopenharmony_ci LineStream(1) 164e5c31af7Sopenharmony_ci << "mediump float H = coords.x, S = coords.y, L = coords.z;" 165e5c31af7Sopenharmony_ci << "mediump float v = (L <= 0.5) ? (L * (1.0 + S)) : (L + S - L * S);" 166e5c31af7Sopenharmony_ci << "res = vec3(L); // default to gray" 167e5c31af7Sopenharmony_ci << "if (v > 0.0)" 168e5c31af7Sopenharmony_ci << "{" 169e5c31af7Sopenharmony_ci << " mediump float m = L + L - v;" 170e5c31af7Sopenharmony_ci << " mediump float sv = (v - m) / v;" 171e5c31af7Sopenharmony_ci << " H *= 6.0;" 172e5c31af7Sopenharmony_ci << " mediump int sextant = int(H);" 173e5c31af7Sopenharmony_ci << " mediump float fract = H - float(sextant);" 174e5c31af7Sopenharmony_ci << " mediump float vsf = v * sv * fract;" 175e5c31af7Sopenharmony_ci << " mediump float mid1 = m + vsf;" 176e5c31af7Sopenharmony_ci << " mediump float mid2 = m - vsf;" 177e5c31af7Sopenharmony_ci << " if (sextant == 0) res = vec3(v, mid1, m);" 178e5c31af7Sopenharmony_ci << " else if (sextant == 1) res = vec3(mid2, v, m);" 179e5c31af7Sopenharmony_ci << " else if (sextant == 2) res = vec3(m, v, mid1);" 180e5c31af7Sopenharmony_ci << " else if (sextant == 3) res = vec3(m, mid2, v);" 181e5c31af7Sopenharmony_ci << " else if (sextant == 4) res = vec3(mid1, m, v);" 182e5c31af7Sopenharmony_ci << " else res = vec3(v, m, mid2);" 183e5c31af7Sopenharmony_ci << "}", 184e5c31af7Sopenharmony_ci { 185e5c31af7Sopenharmony_ci float H = c.unitCoords.x(); 186e5c31af7Sopenharmony_ci float S = c.unitCoords.y(); 187e5c31af7Sopenharmony_ci float L = c.unitCoords.z(); 188e5c31af7Sopenharmony_ci Vec3 rgb = Vec3(L); 189e5c31af7Sopenharmony_ci float v = (L <= 0.5f) ? (L * (1.0f + S)) : (L + S - L * S); 190e5c31af7Sopenharmony_ci if (v > 0.0f) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci float m = L + L - v; 193e5c31af7Sopenharmony_ci float sv = (v - m) / v; 194e5c31af7Sopenharmony_ci H *= 6.0f; 195e5c31af7Sopenharmony_ci int sextant = int(H); 196e5c31af7Sopenharmony_ci float fract = H - float(sextant); 197e5c31af7Sopenharmony_ci float vsf = v * sv * fract; 198e5c31af7Sopenharmony_ci float mid1 = m + vsf; 199e5c31af7Sopenharmony_ci float mid2 = m - vsf; 200e5c31af7Sopenharmony_ci if (sextant == 0) rgb = Vec3(v, mid1, m); 201e5c31af7Sopenharmony_ci else if (sextant == 1) rgb = Vec3(mid2, v, m); 202e5c31af7Sopenharmony_ci else if (sextant == 2) rgb = Vec3(m, v, mid1); 203e5c31af7Sopenharmony_ci else if (sextant == 3) rgb = Vec3(m, mid2, v); 204e5c31af7Sopenharmony_ci else if (sextant == 4) rgb = Vec3(mid1, m, v); 205e5c31af7Sopenharmony_ci else rgb = Vec3(v, m, mid2); 206e5c31af7Sopenharmony_ci } 207e5c31af7Sopenharmony_ci c.color.xyz() = rgb; 208e5c31af7Sopenharmony_ci }); 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci SHADER_OP_CASE(rgb_to_hsl, "Conversion from RGB color space into HSL.", 211e5c31af7Sopenharmony_ci LineStream(1) 212e5c31af7Sopenharmony_ci << "mediump float r = coords.x, g = coords.y, b = coords.z;" 213e5c31af7Sopenharmony_ci << "mediump float minVal = min(min(r, g), b);" 214e5c31af7Sopenharmony_ci << "mediump float maxVal = max(max(r, g), b);" 215e5c31af7Sopenharmony_ci << "mediump float L = (minVal + maxVal) * 0.5;" 216e5c31af7Sopenharmony_ci << "if (minVal == maxVal)" 217e5c31af7Sopenharmony_ci << " res = vec3(0.0, 0.0, L);" 218e5c31af7Sopenharmony_ci << "else" 219e5c31af7Sopenharmony_ci << "{" 220e5c31af7Sopenharmony_ci << " mediump float H;" 221e5c31af7Sopenharmony_ci << " mediump float S;" 222e5c31af7Sopenharmony_ci << " if (L < 0.5)" 223e5c31af7Sopenharmony_ci << " S = (maxVal - minVal) / (maxVal + minVal);" 224e5c31af7Sopenharmony_ci << " else" 225e5c31af7Sopenharmony_ci << " S = (maxVal - minVal) / (2.0 - maxVal - minVal);" 226e5c31af7Sopenharmony_ci << "" 227e5c31af7Sopenharmony_ci << " mediump float ooDiff = 1.0 / (maxVal - minVal);" 228e5c31af7Sopenharmony_ci << " if (r == maxVal) H = (g - b) * ooDiff;" 229e5c31af7Sopenharmony_ci << " else if (g == maxVal) H = 2.0 + (b - r) * ooDiff;" 230e5c31af7Sopenharmony_ci << " else H = 4.0 + (r - g) * ooDiff;" 231e5c31af7Sopenharmony_ci << " H /= 6.0;" 232e5c31af7Sopenharmony_ci << "" 233e5c31af7Sopenharmony_ci << " res = vec3(H, S, L);" 234e5c31af7Sopenharmony_ci << "}", 235e5c31af7Sopenharmony_ci { 236e5c31af7Sopenharmony_ci float r = c.unitCoords.x(); 237e5c31af7Sopenharmony_ci float g = c.unitCoords.y(); 238e5c31af7Sopenharmony_ci float b = c.unitCoords.z(); 239e5c31af7Sopenharmony_ci float minVal = min(min(r, g), b); 240e5c31af7Sopenharmony_ci float maxVal = max(max(r, g), b); 241e5c31af7Sopenharmony_ci float L = (minVal + maxVal) * 0.5f; 242e5c31af7Sopenharmony_ci Vec3 hsl; 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci if (minVal == maxVal) 245e5c31af7Sopenharmony_ci hsl = Vec3(0.0f, 0.0f, L); 246e5c31af7Sopenharmony_ci else 247e5c31af7Sopenharmony_ci { 248e5c31af7Sopenharmony_ci float H; 249e5c31af7Sopenharmony_ci float S; 250e5c31af7Sopenharmony_ci if (L < 0.5f) 251e5c31af7Sopenharmony_ci S = (maxVal - minVal) / (maxVal + minVal); 252e5c31af7Sopenharmony_ci else 253e5c31af7Sopenharmony_ci S = (maxVal - minVal) / (2.0f - maxVal - minVal); 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ci float ooDiff = 1.0f / (maxVal - minVal); 256e5c31af7Sopenharmony_ci if (r == maxVal) H = (g - b) * ooDiff; 257e5c31af7Sopenharmony_ci else if (g == maxVal) H = 2.0f + (b - r) * ooDiff; 258e5c31af7Sopenharmony_ci else H = 4.0f + (r - g) * ooDiff; 259e5c31af7Sopenharmony_ci H /= 6.0f; 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci hsl = Vec3(H, S, L); 262e5c31af7Sopenharmony_ci } 263e5c31af7Sopenharmony_ci c.color.xyz() = hsl; 264e5c31af7Sopenharmony_ci }); 265e5c31af7Sopenharmony_ci 266e5c31af7Sopenharmony_ci/* SHADER_OP_CASE(image_to_grayscale, "Convert image to grayscale.", 267e5c31af7Sopenharmony_ci LineStream(1) 268e5c31af7Sopenharmony_ci << "res = texture2D(ut_brick, coords.xy).rgb;", 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci c.color.xyz() = Vec3(0.5f); 271e5c31af7Sopenharmony_ci });*/ 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ci} // Functional 275e5c31af7Sopenharmony_ci} // gles2 276e5c31af7Sopenharmony_ci} // deqp 277