/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 2.0 Module * ------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * 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 * \brief Shader struct tests. *//*--------------------------------------------------------------------*/ #include "es2fShaderFunctionTests.hpp" #include "glsShaderRenderCase.hpp" #include "gluTexture.hpp" #include "tcuStringTemplate.hpp" #include "tcuTextureUtil.hpp" using namespace deqp::gls; namespace deqp { namespace gles2 { namespace Functional { typedef void (*SetupUniformsFunc)(const glw::Functions &gl, uint32_t programID, const tcu::Vec4 &constCoords); class ShaderFunctionCase : public ShaderRenderCase { public: ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char *vertShaderSource, const char *fragShaderSource); ~ShaderFunctionCase(void); void init(void); void deinit(void); virtual void setupUniforms(int programID, const tcu::Vec4 &constCoords); private: ShaderFunctionCase(const ShaderFunctionCase &); ShaderFunctionCase &operator=(const ShaderFunctionCase &); const SetupUniformsFunc m_setupUniforms; glu::Texture2D *m_brickTexture; }; ShaderFunctionCase::ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char *vertShaderSource, const char *fragShaderSource) : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc) , m_setupUniforms(setupUniformsFunc) , m_brickTexture(DE_NULL) { m_vertShaderSource = vertShaderSource; m_fragShaderSource = fragShaderSource; } ShaderFunctionCase::~ShaderFunctionCase(void) { delete m_brickTexture; } void ShaderFunctionCase::init(void) { gls::ShaderRenderCase::init(); } void ShaderFunctionCase::deinit(void) { gls::ShaderRenderCase::deinit(); delete m_brickTexture; m_brickTexture = DE_NULL; } void ShaderFunctionCase::setupUniforms(int programID, const tcu::Vec4 &constCoords) { ShaderRenderCase::setupUniforms(programID, constCoords); if (m_setupUniforms) m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords); } static ShaderFunctionCase *createStructCase(Context &context, const char *name, const char *description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream &shaderSrc, const std::map *additionalParams) { static const char *defaultVertSrc = "attribute highp vec4 a_position;\n" "attribute highp vec4 a_coords;\n" "varying mediump vec4 v_coords;\n\n" "void main (void)\n" "{\n" " v_coords = a_coords;\n" " gl_Position = a_position;\n" "}\n"; static const char *defaultFragSrc = "varying mediump vec4 v_color;\n\n" "void main (void)\n" "{\n" " gl_FragColor = v_color;\n" "}\n"; // Fill in specialization parameters. std::map spParams; if (isVertexCase) { spParams["DECLARATIONS"] = "attribute highp vec4 a_position;\n" "attribute highp vec4 a_coords;\n" "varying mediump vec4 v_color;"; spParams["COORDS"] = "a_coords"; spParams["DST"] = "v_color"; spParams["ASSIGN_POS"] = "gl_Position = a_position;"; } else { spParams["DECLARATIONS"] = "precision highp float;\n" "varying mediump vec4 v_coords;"; spParams["COORDS"] = "v_coords"; spParams["DST"] = "gl_FragColor"; spParams["ASSIGN_POS"] = ""; } if (additionalParams) spParams.insert(additionalParams->begin(), additionalParams->end()); if (isVertexCase) return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc); else return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, defaultVertSrc, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str()); } ShaderFunctionTests::ShaderFunctionTests(Context &context) : TestCaseGroup(context, "function", "Function Tests") { } ShaderFunctionTests::~ShaderFunctionTests(void) { } void ShaderFunctionTests::init(void) { #define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \ do \ { \ struct Eval_##NAME \ { \ static void eval(ShaderEvalContext &c) EVAL_FUNC_BODY \ }; /* NOLINT(EVAL_FUNC_BODY) */ \ addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, DE_NULL, \ SHADER_SRC, PARAMS)); \ addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, DE_NULL, \ SHADER_SRC, PARAMS)); \ } while (false) #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \ FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL) FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable", LineStream() << "${DECLARATIONS}" << "" << "bool out_params_are_distinct(float x, out float y)" << "{" << " y = 2.;" << " return x == 1. && y == 2.;" << "}" << "" << "void main (void)" << "{" << " float x = 1.;" << " ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);" << " ${ASSIGN_POS}" << "}", { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); }); FUNCTION_CASE( global_variable_aliasing, "Function out parameter aliases global variable", LineStream() << "${DECLARATIONS}" << "" << "" << "float x = 1.;" << "bool out_params_are_distinct_from_global(out float y) {" << " y = 2.;" << " return x == 1. && y == 2.;" << "}" << "" << "void main (void)" << "{" << " ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);" << " ${ASSIGN_POS}" << "}", { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); }); } } // namespace Functional } // namespace gles2 } // namespace deqp