xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fShaderFunctionTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.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 "es3fShaderFunctionTests.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 gles3
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                        bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
46                        const char *vertShaderSource, 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     SetupUniformsFunc m_setupUniforms;
59     bool m_usesTexture;
60 
61     glu::Texture2D *m_brickTexture;
62 };
63 
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)64 ShaderFunctionCase::ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase,
65                                        bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
66                                        const char *vertShaderSource, const char *fragShaderSource)
67     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
68                        description, isVertexCase, evalFunc)
69     , m_setupUniforms(setupUniformsFunc)
70     , m_usesTexture(usesTextures)
71     , m_brickTexture(DE_NULL)
72 {
73     m_vertShaderSource = vertShaderSource;
74     m_fragShaderSource = fragShaderSource;
75 }
76 
~ShaderFunctionCase(void)77 ShaderFunctionCase::~ShaderFunctionCase(void)
78 {
79     delete m_brickTexture;
80 }
81 
init(void)82 void ShaderFunctionCase::init(void)
83 {
84     if (m_usesTexture)
85     {
86         m_brickTexture = glu::Texture2D::create(m_renderCtx, m_ctxInfo, m_testCtx.getArchive(), "data/brick.png");
87         m_textures.push_back(TextureBinding(
88             m_brickTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
89                                          tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
90         DE_ASSERT(m_textures.size() == 1);
91     }
92     gls::ShaderRenderCase::init();
93 }
94 
deinit(void)95 void ShaderFunctionCase::deinit(void)
96 {
97     gls::ShaderRenderCase::deinit();
98     delete m_brickTexture;
99     m_brickTexture = DE_NULL;
100 }
101 
setupUniforms(int programID,const tcu::Vec4 & constCoords)102 void ShaderFunctionCase::setupUniforms(int programID, const tcu::Vec4 &constCoords)
103 {
104     ShaderRenderCase::setupUniforms(programID, constCoords);
105     if (m_setupUniforms)
106         m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
107 }
108 
createStructCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniforms,const LineStream & shaderSrc,const std::map<std::string,std::string> * additionalParams)109 static ShaderFunctionCase *createStructCase(Context &context, const char *name, const char *description,
110                                             bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc,
111                                             SetupUniformsFunc setupUniforms, const LineStream &shaderSrc,
112                                             const std::map<std::string, std::string> *additionalParams)
113 {
114     static const char *defaultVertSrc = "#version 300 es\n"
115                                         "in highp vec4 a_position;\n"
116                                         "in highp vec4 a_coords;\n"
117                                         "out mediump vec4 v_coords;\n\n"
118                                         "void main (void)\n"
119                                         "{\n"
120                                         "    v_coords = a_coords;\n"
121                                         "    gl_Position = a_position;\n"
122                                         "}\n";
123     static const char *defaultFragSrc = "#version 300 es\n"
124                                         "in mediump vec4 v_color;\n"
125                                         "layout(location = 0) out mediump vec4 o_color;\n\n"
126                                         "void main (void)\n"
127                                         "{\n"
128                                         "    o_color = v_color;\n"
129                                         "}\n";
130 
131     // Fill in specialization parameters.
132     std::map<std::string, std::string> spParams;
133     if (isVertexCase)
134     {
135         spParams["HEADER"]     = "#version 300 es\n"
136                                  "in highp vec4 a_position;\n"
137                                  "in highp vec4 a_coords;\n"
138                                  "out mediump vec4 v_color;";
139         spParams["COORDS"]     = "a_coords";
140         spParams["DST"]        = "v_color";
141         spParams["ASSIGN_POS"] = "gl_Position = a_position;";
142     }
143     else
144     {
145         spParams["HEADER"]     = "#version 300 es\n"
146                                  "precision mediump float;\n"
147                                  "in mediump vec4 v_coords;\n"
148                                  "layout(location = 0) out mediump vec4 o_color;";
149         spParams["COORDS"]     = "v_coords";
150         spParams["DST"]        = "o_color";
151         spParams["ASSIGN_POS"] = "";
152     }
153     if (additionalParams)
154         spParams.insert(additionalParams->begin(), additionalParams->end());
155 
156     if (isVertexCase)
157         return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
158                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
159                                       defaultFragSrc);
160     else
161         return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
162                                       defaultVertSrc,
163                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
164 }
165 
ShaderFunctionTests(Context & context)166 ShaderFunctionTests::ShaderFunctionTests(Context &context) : TestCaseGroup(context, "function", "Function Tests")
167 {
168 }
169 
~ShaderFunctionTests(void)170 ShaderFunctionTests::~ShaderFunctionTests(void)
171 {
172 }
173 
init(void)174 void ShaderFunctionTests::init(void)
175 {
176 #define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS)                           \
177     do                                                                                                               \
178     {                                                                                                                \
179         struct Eval_##NAME                                                                                           \
180         {                                                                                                            \
181             static void eval(ShaderEvalContext &c) EVAL_FUNC_BODY                                                    \
182         }; /* NOLINT(EVAL_FUNC_BODY) */                                                                              \
183         addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, \
184                                   SHADER_SRC, PARAMS));                                                              \
185         addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false, &Eval_##NAME::eval,       \
186                                   DE_NULL, SHADER_SRC, PARAMS));                                                     \
187     } while (false)
188 
189 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
190     FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
191 
192     FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
193                   LineStream() << "${HEADER}"
194                                << ""
195                                << "bool out_params_are_distinct(float x, out float y) {"
196                                << "    y = 2.;"
197                                << "    return x == 1. && y == 2.;"
198                                << "}"
199                                << ""
200                                << "void main (void)"
201                                << "{"
202                                << "    float x = 1.;"
203                                << "    ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
204                                << "    ${ASSIGN_POS}"
205                                << "}",
206                   { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
207 
208     FUNCTION_CASE(
209         global_variable_aliasing, "Function out parameter aliases global variable",
210         LineStream() << "${HEADER}"
211                      << ""
212                      << ""
213                      << "float x = 1.;"
214                      << "bool out_params_are_distinct_from_global(out float y) {"
215                      << "    y = 2.;"
216                      << "    return x == 1. && y == 2.;"
217                      << "}"
218                      << ""
219                      << "void main (void)"
220                      << "{"
221                      << "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
222                      << "    ${ASSIGN_POS}"
223                      << "}",
224         { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
225 }
226 
227 } // namespace Functional
228 } // namespace gles3
229 } // namespace deqp
230