1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 2.0 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Shader struct tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es2fShaderFunctionTests.hpp" 25#include "glsShaderRenderCase.hpp" 26#include "gluTexture.hpp" 27#include "tcuStringTemplate.hpp" 28#include "tcuTextureUtil.hpp" 29 30using namespace deqp::gls; 31 32namespace deqp 33{ 34namespace gles2 35{ 36namespace Functional 37{ 38 39typedef void (*SetupUniformsFunc) (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords); 40 41class ShaderFunctionCase : public ShaderRenderCase 42{ 43public: 44 ShaderFunctionCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource); 45 ~ShaderFunctionCase (void); 46 47 void init (void); 48 void deinit (void); 49 50 virtual void setupUniforms (int programID, const tcu::Vec4& constCoords); 51 52private: 53 ShaderFunctionCase (const ShaderFunctionCase&); 54 ShaderFunctionCase& operator= (const ShaderFunctionCase&); 55 56 const SetupUniformsFunc m_setupUniforms; 57 58 glu::Texture2D* m_brickTexture; 59}; 60 61ShaderFunctionCase::ShaderFunctionCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource) 62 : ShaderRenderCase (context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc) 63 , m_setupUniforms (setupUniformsFunc) 64 , m_brickTexture (DE_NULL) 65{ 66 m_vertShaderSource = vertShaderSource; 67 m_fragShaderSource = fragShaderSource; 68} 69 70ShaderFunctionCase::~ShaderFunctionCase (void) 71{ 72 delete m_brickTexture; 73} 74 75void ShaderFunctionCase::init (void) 76{ 77 gls::ShaderRenderCase::init(); 78} 79 80void ShaderFunctionCase::deinit (void) 81{ 82 gls::ShaderRenderCase::deinit(); 83 delete m_brickTexture; 84 m_brickTexture = DE_NULL; 85} 86 87void ShaderFunctionCase::setupUniforms (int programID, const tcu::Vec4& constCoords) 88{ 89 ShaderRenderCase::setupUniforms(programID, constCoords); 90 if (m_setupUniforms) 91 m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords); 92} 93 94static ShaderFunctionCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams) 95{ 96 static const char* defaultVertSrc = 97 "attribute highp vec4 a_position;\n" 98 "attribute highp vec4 a_coords;\n" 99 "varying mediump vec4 v_coords;\n\n" 100 "void main (void)\n" 101 "{\n" 102 " v_coords = a_coords;\n" 103 " gl_Position = a_position;\n" 104 "}\n"; 105 static const char* defaultFragSrc = 106 "varying mediump vec4 v_color;\n\n" 107 "void main (void)\n" 108 "{\n" 109 " gl_FragColor = v_color;\n" 110 "}\n"; 111 112 // Fill in specialization parameters. 113 std::map<std::string, std::string> spParams; 114 if (isVertexCase) 115 { 116 spParams["DECLARATIONS"] = 117 "attribute highp vec4 a_position;\n" 118 "attribute highp vec4 a_coords;\n" 119 "varying mediump vec4 v_color;"; 120 spParams["COORDS"] = "a_coords"; 121 spParams["DST"] = "v_color"; 122 spParams["ASSIGN_POS"] = "gl_Position = a_position;"; 123 } 124 else 125 { 126 spParams["DECLARATIONS"] = 127 "precision highp float;\n" 128 "varying mediump vec4 v_coords;"; 129 spParams["COORDS"] = "v_coords"; 130 spParams["DST"] = "gl_FragColor"; 131 spParams["ASSIGN_POS"] = ""; 132 } 133 if (additionalParams) 134 spParams.insert(additionalParams->begin(), additionalParams->end()); 135 136 if (isVertexCase) 137 return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc); 138 else 139 return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, defaultVertSrc, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str()); 140} 141 142ShaderFunctionTests::ShaderFunctionTests (Context& context) 143 : TestCaseGroup(context, "function", "Function Tests") 144{ 145} 146 147ShaderFunctionTests::~ShaderFunctionTests (void) 148{ 149} 150 151void ShaderFunctionTests::init (void) 152{ 153 #define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \ 154 do { \ 155 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \ 156 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS)); \ 157 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\ 158 } while (deGetFalse()) 159 160 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \ 161 FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL) 162 163 FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable", 164 LineStream() 165 << "${DECLARATIONS}" 166 << "" 167 << "bool out_params_are_distinct(float x, out float y)" 168 << "{" 169 << " y = 2.;" 170 << " return x == 1. && y == 2.;" 171 << "}" 172 << "" 173 << "void main (void)" 174 << "{" 175 << " float x = 1.;" 176 << " ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);" 177 << " ${ASSIGN_POS}" 178 << "}", 179 { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); }); 180 181 FUNCTION_CASE(global_variable_aliasing, "Function out parameter aliases global variable", 182 LineStream() 183 << "${DECLARATIONS}" 184 << "" 185 << "" 186 << "float x = 1.;" 187 << "bool out_params_are_distinct_from_global(out float y) {" 188 << " y = 2.;" 189 << " return x == 1. && y == 2.;" 190 << "}" 191 << "" 192 << "void main (void)" 193 << "{" 194 << " ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);" 195 << " ${ASSIGN_POS}" 196 << "}", 197 { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); }); 198} 199 200} // Functional 201} // gles2 202} // deqp 203