xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fShaderFunctionTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 
30 using namespace deqp::gls;
31 
32 namespace deqp
33 {
34 namespace gles2
35 {
36 namespace Functional
37 {
38 
39 typedef void (*SetupUniformsFunc)(const glw::Functions &gl, uint32_t programID, const tcu::Vec4 &constCoords);
40 
41 class ShaderFunctionCase : public ShaderRenderCase
42 {
43 public:
44     ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase,
45                        ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char *vertShaderSource,
46                        const char *fragShaderSource);
47     ~ShaderFunctionCase(void);
48 
49     void init(void);
50     void deinit(void);
51 
52     virtual void setupUniforms(int programID, const tcu::Vec4 &constCoords);
53 
54 private:
55     ShaderFunctionCase(const ShaderFunctionCase &);
56     ShaderFunctionCase &operator=(const ShaderFunctionCase &);
57 
58     const SetupUniformsFunc m_setupUniforms;
59 
60     glu::Texture2D *m_brickTexture;
61 };
62 
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)63 ShaderFunctionCase::ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase,
64                                        ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
65                                        const char *vertShaderSource, const char *fragShaderSource)
66     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
67                        description, isVertexCase, evalFunc)
68     , m_setupUniforms(setupUniformsFunc)
69     , m_brickTexture(DE_NULL)
70 {
71     m_vertShaderSource = vertShaderSource;
72     m_fragShaderSource = fragShaderSource;
73 }
74 
~ShaderFunctionCase(void)75 ShaderFunctionCase::~ShaderFunctionCase(void)
76 {
77     delete m_brickTexture;
78 }
79 
init(void)80 void ShaderFunctionCase::init(void)
81 {
82     gls::ShaderRenderCase::init();
83 }
84 
deinit(void)85 void ShaderFunctionCase::deinit(void)
86 {
87     gls::ShaderRenderCase::deinit();
88     delete m_brickTexture;
89     m_brickTexture = DE_NULL;
90 }
91 
setupUniforms(int programID,const tcu::Vec4 & constCoords)92 void ShaderFunctionCase::setupUniforms(int programID, const tcu::Vec4 &constCoords)
93 {
94     ShaderRenderCase::setupUniforms(programID, constCoords);
95     if (m_setupUniforms)
96         m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
97 }
98 
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)99 static ShaderFunctionCase *createStructCase(Context &context, const char *name, const char *description,
100                                             bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms,
101                                             const LineStream &shaderSrc,
102                                             const std::map<std::string, std::string> *additionalParams)
103 {
104     static const char *defaultVertSrc = "attribute highp vec4 a_position;\n"
105                                         "attribute highp vec4 a_coords;\n"
106                                         "varying mediump vec4 v_coords;\n\n"
107                                         "void main (void)\n"
108                                         "{\n"
109                                         "    v_coords = a_coords;\n"
110                                         "    gl_Position = a_position;\n"
111                                         "}\n";
112     static const char *defaultFragSrc = "varying mediump vec4 v_color;\n\n"
113                                         "void main (void)\n"
114                                         "{\n"
115                                         "    gl_FragColor = v_color;\n"
116                                         "}\n";
117 
118     // Fill in specialization parameters.
119     std::map<std::string, std::string> spParams;
120     if (isVertexCase)
121     {
122         spParams["DECLARATIONS"] = "attribute highp vec4 a_position;\n"
123                                    "attribute highp vec4 a_coords;\n"
124                                    "varying mediump vec4 v_color;";
125         spParams["COORDS"]       = "a_coords";
126         spParams["DST"]          = "v_color";
127         spParams["ASSIGN_POS"]   = "gl_Position = a_position;";
128     }
129     else
130     {
131         spParams["DECLARATIONS"] = "precision highp float;\n"
132                                    "varying mediump vec4 v_coords;";
133         spParams["COORDS"]       = "v_coords";
134         spParams["DST"]          = "gl_FragColor";
135         spParams["ASSIGN_POS"]   = "";
136     }
137     if (additionalParams)
138         spParams.insert(additionalParams->begin(), additionalParams->end());
139 
140     if (isVertexCase)
141         return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms,
142                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
143                                       defaultFragSrc);
144     else
145         return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, defaultVertSrc,
146                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
147 }
148 
ShaderFunctionTests(Context & context)149 ShaderFunctionTests::ShaderFunctionTests(Context &context) : TestCaseGroup(context, "function", "Function Tests")
150 {
151 }
152 
~ShaderFunctionTests(void)153 ShaderFunctionTests::~ShaderFunctionTests(void)
154 {
155 }
156 
init(void)157 void ShaderFunctionTests::init(void)
158 {
159 #define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS)                       \
160     do                                                                                                           \
161     {                                                                                                            \
162         struct Eval_##NAME                                                                                       \
163         {                                                                                                        \
164             static void eval(ShaderEvalContext &c) EVAL_FUNC_BODY                                                \
165         }; /* NOLINT(EVAL_FUNC_BODY) */                                                                          \
166         addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, DE_NULL,    \
167                                   SHADER_SRC, PARAMS));                                                          \
168         addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, DE_NULL, \
169                                   SHADER_SRC, PARAMS));                                                          \
170     } while (false)
171 
172 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
173     FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
174 
175     FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
176                   LineStream() << "${DECLARATIONS}"
177                                << ""
178                                << "bool out_params_are_distinct(float x, out float y)"
179                                << "{"
180                                << "    y = 2.;"
181                                << "    return x == 1. && y == 2.;"
182                                << "}"
183                                << ""
184                                << "void main (void)"
185                                << "{"
186                                << "    float x = 1.;"
187                                << "    ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
188                                << "    ${ASSIGN_POS}"
189                                << "}",
190                   { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
191 
192     FUNCTION_CASE(
193         global_variable_aliasing, "Function out parameter aliases global variable",
194         LineStream() << "${DECLARATIONS}"
195                      << ""
196                      << ""
197                      << "float x = 1.;"
198                      << "bool out_params_are_distinct_from_global(out float y) {"
199                      << "    y = 2.;"
200                      << "    return x == 1. && y == 2.;"
201                      << "}"
202                      << ""
203                      << "void main (void)"
204                      << "{"
205                      << "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
206                      << "    ${ASSIGN_POS}"
207                      << "}",
208         { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
209 }
210 
211 } // namespace Functional
212 } // namespace gles2
213 } // namespace deqp
214