xref: /aosp_15_r20/external/deqp/modules/glshared/glsShaderRenderCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GLSSHADERRENDERCASE_HPP
2 #define _GLSSHADERRENDERCASE_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL (ES) Module
5  * -----------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Shader execute test.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 #include "tcuTestCase.hpp"
28 #include "tcuVector.hpp"
29 #include "tcuMatrix.hpp"
30 #include "tcuTexture.hpp"
31 #include "tcuSurface.hpp"
32 #include "gluRenderContext.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluShaderProgram.hpp"
35 
36 #include <sstream>
37 #include <string>
38 
39 namespace glu
40 {
41 class RenderContext;
42 class Texture2D;
43 class TextureCube;
44 class Texture2DArray;
45 class Texture3D;
46 } // namespace glu
47 
48 namespace deqp
49 {
50 namespace gls
51 {
52 
53 // LineStream \todo [2011-10-17 pyry] Move to proper place!
54 
55 class LineStream
56 {
57 public:
LineStream(int indent=0)58     LineStream(int indent = 0)
59     {
60         m_indent = indent;
61     }
~LineStream(void)62     ~LineStream(void)
63     {
64     }
65 
str(void) const66     const char *str(void) const
67     {
68         m_string = m_stream.str();
69         return m_string.c_str();
70     }
operator <<(const char * line)71     LineStream &operator<<(const char *line)
72     {
73         for (int i = 0; i < m_indent; i++)
74         {
75             m_stream << "\t";
76         }
77         m_stream << line << "\n";
78         return *this;
79     }
80 
81 private:
82     int m_indent;
83     std::ostringstream m_stream;
84     mutable std::string m_string;
85 };
86 
87 class QuadGrid;
88 
89 // TextureBinding
90 
91 class TextureBinding
92 {
93 public:
94     enum Type
95     {
96         TYPE_NONE = 0,
97         TYPE_2D,
98         TYPE_CUBE_MAP,
99         TYPE_2D_ARRAY,
100         TYPE_3D,
101 
102         TYPE_LAST
103     };
104 
105     TextureBinding(const glu::Texture2D *tex2D, const tcu::Sampler &sampler);
106     TextureBinding(const glu::TextureCube *texCube, const tcu::Sampler &sampler);
107     TextureBinding(const glu::Texture2DArray *tex2DArray, const tcu::Sampler &sampler);
108     TextureBinding(const glu::Texture3D *tex3D, const tcu::Sampler &sampler);
109     TextureBinding(void);
110 
111     void setSampler(const tcu::Sampler &sampler);
112     void setTexture(const glu::Texture2D *tex2D);
113     void setTexture(const glu::TextureCube *texCube);
114     void setTexture(const glu::Texture2DArray *tex2DArray);
115     void setTexture(const glu::Texture3D *tex3D);
116 
getType(void) const117     Type getType(void) const
118     {
119         return m_type;
120     }
getSampler(void) const121     const tcu::Sampler &getSampler(void) const
122     {
123         return m_sampler;
124     }
get2D(void) const125     const glu::Texture2D *get2D(void) const
126     {
127         DE_ASSERT(getType() == TYPE_2D);
128         return m_binding.tex2D;
129     }
getCube(void) const130     const glu::TextureCube *getCube(void) const
131     {
132         DE_ASSERT(getType() == TYPE_CUBE_MAP);
133         return m_binding.texCube;
134     }
get2DArray(void) const135     const glu::Texture2DArray *get2DArray(void) const
136     {
137         DE_ASSERT(getType() == TYPE_2D_ARRAY);
138         return m_binding.tex2DArray;
139     }
get3D(void) const140     const glu::Texture3D *get3D(void) const
141     {
142         DE_ASSERT(getType() == TYPE_3D);
143         return m_binding.tex3D;
144     }
145 
146 private:
147     Type m_type;
148     tcu::Sampler m_sampler;
149     union
150     {
151         const glu::Texture2D *tex2D;
152         const glu::TextureCube *texCube;
153         const glu::Texture2DArray *tex2DArray;
154         const glu::Texture3D *tex3D;
155     } m_binding;
156 };
157 
158 // ShaderEvalContext.
159 
160 class ShaderEvalContext
161 {
162 public:
163     // Limits.
164     enum
165     {
166         MAX_USER_ATTRIBS = 4,
167         MAX_TEXTURES     = 4,
168     };
169 
170     struct ShaderSampler
171     {
172         tcu::Sampler sampler;
173         const tcu::Texture2D *tex2D;
174         const tcu::TextureCube *texCube;
175         const tcu::Texture2DArray *tex2DArray;
176         const tcu::Texture3D *tex3D;
177 
ShaderSamplerdeqp::gls::ShaderEvalContext::ShaderSampler178         inline ShaderSampler(void) : tex2D(DE_NULL), texCube(DE_NULL), tex2DArray(DE_NULL), tex3D(DE_NULL)
179         {
180         }
181     };
182 
183     ShaderEvalContext(const QuadGrid &quadGrid);
184     ~ShaderEvalContext(void);
185 
186     void reset(float sx, float sy);
187 
188     // Inputs.
189     tcu::Vec4 coords;
190     tcu::Vec4 unitCoords;
191     tcu::Vec4 constCoords;
192 
193     tcu::Vec4 in[MAX_USER_ATTRIBS];
194     ShaderSampler textures[MAX_TEXTURES];
195 
196     // Output.
197     tcu::Vec4 color;
198     bool isDiscarded;
199 
200     // Functions.
discard(void)201     inline void discard(void)
202     {
203         isDiscarded = true;
204     }
205     tcu::Vec4 texture2D(int unitNdx, const tcu::Vec2 &coords);
206 
207 private:
208     const QuadGrid &quadGrid;
209 };
210 
211 // ShaderEvalFunc.
212 
213 typedef void (*ShaderEvalFunc)(ShaderEvalContext &c);
214 
evalCoordsPassthroughX(ShaderEvalContext & c)215 inline void evalCoordsPassthroughX(ShaderEvalContext &c)
216 {
217     c.color.x() = c.coords.x();
218 }
evalCoordsPassthroughXY(ShaderEvalContext & c)219 inline void evalCoordsPassthroughXY(ShaderEvalContext &c)
220 {
221     c.color.xy() = c.coords.swizzle(0, 1);
222 }
evalCoordsPassthroughXYZ(ShaderEvalContext & c)223 inline void evalCoordsPassthroughXYZ(ShaderEvalContext &c)
224 {
225     c.color.xyz() = c.coords.swizzle(0, 1, 2);
226 }
evalCoordsPassthrough(ShaderEvalContext & c)227 inline void evalCoordsPassthrough(ShaderEvalContext &c)
228 {
229     c.color = c.coords;
230 }
evalCoordsSwizzleWZYX(ShaderEvalContext & c)231 inline void evalCoordsSwizzleWZYX(ShaderEvalContext &c)
232 {
233     c.color = c.coords.swizzle(3, 2, 1, 0);
234 }
235 
236 // ShaderEvaluator
237 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
238 
239 class ShaderEvaluator
240 {
241 public:
242     ShaderEvaluator(void);
243     ShaderEvaluator(ShaderEvalFunc evalFunc);
244     virtual ~ShaderEvaluator(void);
245 
246     virtual void evaluate(ShaderEvalContext &ctx);
247 
248 private:
249     ShaderEvaluator(const ShaderEvaluator &);            // not allowed!
250     ShaderEvaluator &operator=(const ShaderEvaluator &); // not allowed!
251 
252     ShaderEvalFunc m_evalFunc;
253 };
254 
255 // ShaderRenderCase.
256 
257 class ShaderRenderCase : public tcu::TestCase
258 {
259 public:
260     ShaderRenderCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
261                      const char *name, const char *description, bool isVertexCase, ShaderEvalFunc evalFunc);
262     ShaderRenderCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
263                      const char *name, const char *description, bool isVertexCase, ShaderEvaluator &evaluator);
264     virtual ~ShaderRenderCase(void);
265 
266     void init(void);
267     void deinit(void);
268 
269     IterateResult iterate(void);
270 
271 protected:
272     virtual void setupShaderData(void);
273     virtual void setup(int programID);
274     virtual void setupUniforms(int programID, const tcu::Vec4 &constCoords);
275 
276     tcu::IVec2 getViewportSize(void) const;
277 
278     class CompileFailed : public tcu::TestError
279     {
280     public:
CompileFailed(const char * file,int line)281         inline CompileFailed(const char *file, int line)
282             : tcu::TestError("Failed to compile shader program", DE_NULL, file, line)
283         {
284         }
285     };
286 
287 private:
288     ShaderRenderCase(const ShaderRenderCase &);            // not allowed!
289     ShaderRenderCase &operator=(const ShaderRenderCase &); // not allowed!
290 
291     void setupDefaultInputs(int programID);
292 
293     void render(tcu::Surface &result, int programID, const QuadGrid &quadGrid);
294     void computeVertexReference(tcu::Surface &result, const QuadGrid &quadGrid);
295     void computeFragmentReference(tcu::Surface &result, const QuadGrid &quadGrid);
296     bool compareImages(const tcu::Surface &resImage, const tcu::Surface &refImage, float errorThreshold);
297 
298 protected:
299     glu::RenderContext &m_renderCtx;
300     const glu::ContextInfo &m_ctxInfo;
301 
302     bool m_isVertexCase;
303     ShaderEvaluator m_defaultEvaluator;
304     ShaderEvaluator &m_evaluator;
305     std::string m_vertShaderSource;
306     std::string m_fragShaderSource;
307     tcu::Vec4 m_clearColor;
308 
309     std::vector<tcu::Mat4> m_userAttribTransforms;
310     std::vector<TextureBinding> m_textures;
311 
312     glu::ShaderProgram *m_program;
313     int m_gridSize;
314 };
315 
316 // Helpers.
317 // \todo [2012-04-10 pyry] Move these to separate utility?
318 
319 const char *getIntUniformName(int number);
320 const char *getFloatUniformName(int number);
321 const char *getFloatFractionUniformName(int number);
322 
323 void setupDefaultUniforms(const glu::RenderContext &context, uint32_t programID);
324 
325 } // namespace gls
326 } // namespace deqp
327 
328 #endif // _GLSSHADERRENDERCASE_HPP
329