xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcShaderFunctionTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21  * \file
22  * \brief Shader struct tests.
23  */ /*-------------------------------------------------------------------*/
24 
25 #include "glcShaderFunctionTests.hpp"
26 #include "glcShaderRenderCase.hpp"
27 #include "gluTexture.hpp"
28 #include "tcuStringTemplate.hpp"
29 #include "tcuTextureUtil.hpp"
30 
31 using namespace glu;
32 
33 namespace deqp
34 {
35 
36 typedef void (*SetupUniformsFunc)(const glw::Functions &gl, uint32_t programID, const tcu::Vec4 &constCoords);
37 
38 class ShaderFunctionCase : public ShaderRenderCase
39 {
40 public:
41     ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase,
42                        bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
43                        const char *vertShaderSource, const char *fragShaderSource);
44     ~ShaderFunctionCase(void);
45 
46     void init(void);
47     void deinit(void);
48 
49     virtual void setupUniforms(uint32_t programID, const tcu::Vec4 &constCoords);
50 
51 private:
52     ShaderFunctionCase(const ShaderFunctionCase &);
53     ShaderFunctionCase &operator=(const ShaderFunctionCase &);
54 
55     SetupUniformsFunc m_setupUniforms;
56     bool m_usesTexture;
57 
58     glu::Texture2D *m_gradientTexture;
59 };
60 
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)61 ShaderFunctionCase::ShaderFunctionCase(Context &context, const char *name, const char *description, bool isVertexCase,
62                                        bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
63                                        const char *vertShaderSource, const char *fragShaderSource)
64     : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
65                        description, isVertexCase, evalFunc)
66     , m_setupUniforms(setupUniformsFunc)
67     , m_usesTexture(usesTextures)
68     , m_gradientTexture(DE_NULL)
69 {
70     m_vertShaderSource = vertShaderSource;
71     m_fragShaderSource = fragShaderSource;
72 }
73 
~ShaderFunctionCase(void)74 ShaderFunctionCase::~ShaderFunctionCase(void)
75 {
76 }
77 
init(void)78 void ShaderFunctionCase::init(void)
79 {
80     if (m_usesTexture)
81     {
82         m_gradientTexture = new glu::Texture2D(m_renderCtx, GL_RGBA8, 128, 128);
83 
84         m_gradientTexture->getRefTexture().allocLevel(0);
85         tcu::fillWithComponentGradients(m_gradientTexture->getRefTexture().getLevel(0), tcu::Vec4(0.0f),
86                                         tcu::Vec4(1.0f));
87         m_gradientTexture->upload();
88 
89         m_textures.push_back(TextureBinding(
90             m_gradientTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
91                                             tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
92         DE_ASSERT(m_textures.size() == 1);
93     }
94     ShaderRenderCase::init();
95 }
96 
deinit(void)97 void ShaderFunctionCase::deinit(void)
98 {
99     if (m_usesTexture)
100     {
101         delete m_gradientTexture;
102     }
103     ShaderRenderCase::deinit();
104 }
105 
setupUniforms(uint32_t programID,const tcu::Vec4 & constCoords)106 void ShaderFunctionCase::setupUniforms(uint32_t programID, const tcu::Vec4 &constCoords)
107 {
108     ShaderRenderCase::setupUniforms(programID, constCoords);
109     if (m_setupUniforms)
110         m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
111 }
112 
createStructCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniforms,const LineStream & shaderSrc)113 static ShaderFunctionCase *createStructCase(Context &context, const char *name, const char *description,
114                                             glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures,
115                                             ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms,
116                                             const LineStream &shaderSrc)
117 {
118     const std::string versionDecl = glu::getGLSLVersionDeclaration(glslVersion);
119 
120     const std::string defaultVertSrc = versionDecl + "\n"
121                                                      "in highp vec4 a_position;\n"
122                                                      "in highp vec4 a_coords;\n"
123                                                      "out mediump vec4 v_coords;\n\n"
124                                                      "void main (void)\n"
125                                                      "{\n"
126                                                      "   v_coords = a_coords;\n"
127                                                      "   gl_Position = a_position;\n"
128                                                      "}\n";
129     const std::string defaultFragSrc = versionDecl + "\n"
130                                                      "in mediump vec4 v_color;\n"
131                                                      "layout(location = 0) out mediump vec4 o_color;\n\n"
132                                                      "void main (void)\n"
133                                                      "{\n"
134                                                      "   o_color = v_color;\n"
135                                                      "}\n";
136 
137     // Fill in specialization parameters.
138     std::map<std::string, std::string> spParams;
139     if (isVertexCase)
140     {
141         spParams["HEADER"]     = versionDecl + "\n"
142                                                "in highp vec4 a_position;\n"
143                                                "in highp vec4 a_coords;\n"
144                                                "out mediump vec4 v_color;";
145         spParams["COORDS"]     = "a_coords";
146         spParams["DST"]        = "v_color";
147         spParams["ASSIGN_POS"] = "gl_Position = a_position;";
148     }
149     else
150     {
151         spParams["HEADER"]     = versionDecl + "\n"
152                                                "#ifdef GL_ES\n"
153                                                "    precision mediump float;\n"
154                                                "#endif\n"
155                                                "\n"
156                                                "in mediump vec4 v_coords;\n"
157                                                "layout(location = 0) out mediump vec4 o_color;";
158         spParams["COORDS"]     = "v_coords";
159         spParams["DST"]        = "o_color";
160         spParams["ASSIGN_POS"] = "";
161     }
162 
163     if (isVertexCase)
164         return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
165                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
166                                       defaultFragSrc.c_str());
167     else
168         return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
169                                       defaultVertSrc.c_str(),
170                                       tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
171 }
172 
ShaderFunctionTests(Context & context,glu::GLSLVersion glslVersion)173 ShaderFunctionTests::ShaderFunctionTests(Context &context, glu::GLSLVersion glslVersion)
174     : TestCaseGroup(context, "function", "Function Tests")
175     , m_glslVersion(glslVersion)
176 {
177 }
178 
~ShaderFunctionTests(void)179 ShaderFunctionTests::~ShaderFunctionTests(void)
180 {
181 }
182 
init(void)183 void ShaderFunctionTests::init(void)
184 {
185 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY)                                      \
186     do                                                                                                    \
187     {                                                                                                     \
188         struct Eval_##NAME                                                                                \
189         {                                                                                                 \
190             static void eval(ShaderEvalContext &c) EVAL_FUNC_BODY                                         \
191         };                                                                                                \
192         addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, false,    \
193                                   &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
194         addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, false, \
195                                   &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
196     } while (false)
197 
198     FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
199                   LineStream() << "${HEADER}"
200                                << ""
201                                << "bool out_params_are_distinct(float x, out float y) {"
202                                << "    y = 2.;"
203                                << "    return x == 1. && y == 2.;"
204                                << "}"
205                                << ""
206                                << "void main (void)"
207                                << "{"
208                                << "    float x = 1.;"
209                                << "    ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
210                                << "    ${ASSIGN_POS}"
211                                << "}",
212                   { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
213 
214     FUNCTION_CASE(
215         global_variable_aliasing, "Function out parameter aliases global variable",
216         LineStream() << "${HEADER}"
217                      << ""
218                      << "float x = 1.;"
219                      << "bool out_params_are_distinct_from_global(out float y) {"
220                      << "    y = 2.;"
221                      << "    return x == 1. && y == 2.;"
222                      << "}"
223                      << ""
224                      << "void main (void)"
225                      << "{"
226                      << "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
227                      << "    ${ASSIGN_POS}"
228                      << "}",
229         { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
230 }
231 
232 } // namespace deqp
233