xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcShaderRenderCase.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 #ifndef _GLCSHADERRENDERCASE_HPP
2 #define _GLCSHADERRENDERCASE_HPP
3 /*-------------------------------------------------------------------------
4  * OpenGL Conformance Test Suite
5  * -----------------------------
6  *
7  * Copyright (c) 2016 Google Inc.
8  * Copyright (c) 2016 The Khronos Group Inc.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */ /*!
23  * \file
24  * \brief Shader execute test.
25  */ /*-------------------------------------------------------------------*/
26 
27 #include "glcTestCase.hpp"
28 #include "gluContextInfo.hpp"
29 #include "gluRenderContext.hpp"
30 #include "gluShaderProgram.hpp"
31 #include "tcuDefs.hpp"
32 #include "tcuMatrix.hpp"
33 #include "tcuSurface.hpp"
34 #include "tcuTexture.hpp"
35 #include "tcuVector.hpp"
36 
37 #include <sstream>
38 #include <string>
39 
40 namespace glu
41 {
42 class RenderContext;
43 class Texture2D;
44 class TextureCube;
45 class Texture2DArray;
46 class Texture3D;
47 class TextureCubeArray;
48 } // namespace glu
49 
50 namespace deqp
51 {
52 
53 // LineStream
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         TYPE_CUBE_MAP_ARRAY,
102 
103         TYPE_LAST
104     };
105 
106     TextureBinding(const glu::Texture2D *tex2D, const tcu::Sampler &sampler);
107     TextureBinding(const glu::TextureCube *texCube, const tcu::Sampler &sampler);
108     TextureBinding(const glu::Texture2DArray *tex2DArray, const tcu::Sampler &sampler);
109     TextureBinding(const glu::Texture3D *tex3D, const tcu::Sampler &sampler);
110     TextureBinding(const glu::TextureCubeArray *texCubeArray, const tcu::Sampler &sampler);
111     TextureBinding(void);
112 
113     void setSampler(const tcu::Sampler &sampler);
114     void setTexture(const glu::Texture2D *tex2D);
115     void setTexture(const glu::TextureCube *texCube);
116     void setTexture(const glu::Texture2DArray *tex2DArray);
117     void setTexture(const glu::Texture3D *tex3D);
118     void setTexture(const glu::TextureCubeArray *texCubeArray);
119 
getType(void) const120     Type getType(void) const
121     {
122         return m_type;
123     }
getSampler(void) const124     const tcu::Sampler &getSampler(void) const
125     {
126         return m_sampler;
127     }
get2D(void) const128     const glu::Texture2D *get2D(void) const
129     {
130         DE_ASSERT(getType() == TYPE_2D);
131         return m_binding.tex2D;
132     }
getCube(void) const133     const glu::TextureCube *getCube(void) const
134     {
135         DE_ASSERT(getType() == TYPE_CUBE_MAP);
136         return m_binding.texCube;
137     }
get2DArray(void) const138     const glu::Texture2DArray *get2DArray(void) const
139     {
140         DE_ASSERT(getType() == TYPE_2D_ARRAY);
141         return m_binding.tex2DArray;
142     }
get3D(void) const143     const glu::Texture3D *get3D(void) const
144     {
145         DE_ASSERT(getType() == TYPE_3D);
146         return m_binding.tex3D;
147     }
getCubeArray(void) const148     const glu::TextureCubeArray *getCubeArray(void) const
149     {
150         DE_ASSERT(getType() == TYPE_CUBE_MAP_ARRAY);
151         return m_binding.texCubeArray;
152     }
153 
154 private:
155     Type m_type;
156     tcu::Sampler m_sampler;
157     union
158     {
159         const glu::Texture2D *tex2D;
160         const glu::TextureCube *texCube;
161         const glu::Texture2DArray *tex2DArray;
162         const glu::Texture3D *tex3D;
163         const glu::TextureCubeArray *texCubeArray;
164     } m_binding;
165 };
166 
167 // ShaderEvalContext.
168 
169 class ShaderEvalContext
170 {
171 public:
172     // Limits.
173     enum
174     {
175         MAX_USER_ATTRIBS = 4,
176         MAX_TEXTURES     = 4,
177     };
178 
179     struct ShaderSampler
180     {
181         tcu::Sampler sampler;
182         const tcu::Texture2D *tex2D;
183         const tcu::TextureCube *texCube;
184         const tcu::Texture2DArray *tex2DArray;
185         const tcu::Texture3D *tex3D;
186         const tcu::TextureCubeArray *texCubeArray;
187 
ShaderSamplerdeqp::ShaderEvalContext::ShaderSampler188         inline ShaderSampler(void)
189             : tex2D(DE_NULL)
190             , texCube(DE_NULL)
191             , tex2DArray(DE_NULL)
192             , tex3D(DE_NULL)
193             , texCubeArray(DE_NULL)
194         {
195         }
196     };
197 
198     ShaderEvalContext(const QuadGrid &quadGrid);
199     ~ShaderEvalContext(void);
200 
201     void reset(float sx, float sy);
202 
203     // Inputs.
204     tcu::Vec4 coords;
205     tcu::Vec4 unitCoords;
206     tcu::Vec4 constCoords;
207 
208     tcu::Vec4 in[MAX_USER_ATTRIBS];
209     ShaderSampler textures[MAX_TEXTURES];
210 
211     // Output.
212     tcu::Vec4 color;
213     bool isDiscarded;
214 
215     // Functions.
discard(void)216     inline void discard(void)
217     {
218         isDiscarded = true;
219     }
220     tcu::Vec4 texture2D(int unitNdx, const tcu::Vec2 &coords);
221 
222 private:
223     const QuadGrid &quadGrid;
224 };
225 
226 // ShaderEvalFunc.
227 
228 typedef void (*ShaderEvalFunc)(ShaderEvalContext &c);
229 
evalCoordsPassthroughX(ShaderEvalContext & c)230 inline void evalCoordsPassthroughX(ShaderEvalContext &c)
231 {
232     c.color.x() = c.coords.x();
233 }
evalCoordsPassthroughXY(ShaderEvalContext & c)234 inline void evalCoordsPassthroughXY(ShaderEvalContext &c)
235 {
236     c.color.xy() = c.coords.swizzle(0, 1);
237 }
evalCoordsPassthroughXYZ(ShaderEvalContext & c)238 inline void evalCoordsPassthroughXYZ(ShaderEvalContext &c)
239 {
240     c.color.xyz() = c.coords.swizzle(0, 1, 2);
241 }
evalCoordsPassthrough(ShaderEvalContext & c)242 inline void evalCoordsPassthrough(ShaderEvalContext &c)
243 {
244     c.color = c.coords;
245 }
evalCoordsSwizzleWZYX(ShaderEvalContext & c)246 inline void evalCoordsSwizzleWZYX(ShaderEvalContext &c)
247 {
248     c.color = c.coords.swizzle(3, 2, 1, 0);
249 }
250 
251 // ShaderEvaluator
252 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
253 
254 class ShaderEvaluator
255 {
256 public:
257     ShaderEvaluator(void);
258     ShaderEvaluator(ShaderEvalFunc evalFunc);
259     virtual ~ShaderEvaluator(void);
260 
261     virtual void evaluate(ShaderEvalContext &ctx);
262 
263 private:
264     ShaderEvaluator(const ShaderEvaluator &);            // not allowed!
265     ShaderEvaluator &operator=(const ShaderEvaluator &); // not allowed!
266 
267     ShaderEvalFunc m_evalFunc;
268 };
269 
270 // ShaderRenderCase.
271 
272 class ShaderRenderCase : public tcu::TestCase
273 {
274 public:
275     ShaderRenderCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
276                      const char *name, const char *description, bool isVertexCase, ShaderEvalFunc evalFunc);
277     ShaderRenderCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const glu::ContextInfo &ctxInfo,
278                      const char *name, const char *description, bool isVertexCase, ShaderEvaluator &evaluator);
279     virtual ~ShaderRenderCase(void);
280 
281     void init(void);
282     void deinit(void);
283 
284     IterateResult iterate(void);
285 
286 protected:
287     virtual void setup(uint32_t programID);
288     virtual void setupUniforms(uint32_t programID, const tcu::Vec4 &constCoords);
289 
290     tcu::IVec2 getViewportSize(void) const;
291 
292 private:
293     ShaderRenderCase(const ShaderRenderCase &);            // not allowed!
294     ShaderRenderCase &operator=(const ShaderRenderCase &); // not allowed!
295 
296     void setupDefaultInputs(int programID);
297 
298     void render(tcu::Surface &result, int programID, const QuadGrid &quadGrid);
299     void computeVertexReference(tcu::Surface &result, const QuadGrid &quadGrid);
300     void computeFragmentReference(tcu::Surface &result, const QuadGrid &quadGrid);
301     bool compareImages(const tcu::Surface &resImage, const tcu::Surface &refImage, float errorThreshold);
302 
303 protected:
304     glu::RenderContext &m_renderCtx;
305     const glu::ContextInfo &m_ctxInfo;
306 
307     bool m_isVertexCase;
308     ShaderEvaluator m_defaultEvaluator;
309     ShaderEvaluator &m_evaluator;
310     std::string m_vertShaderSource;
311     std::string m_fragShaderSource;
312     tcu::Vec4 m_clearColor;
313 
314     std::vector<tcu::Mat4> m_userAttribTransforms;
315     std::vector<TextureBinding> m_textures;
316 
317     glu::ShaderProgram *m_program;
318 };
319 
320 // Helpers.
321 // \todo [2012-04-10 pyry] Move these to separate utility?
322 
323 const char *getIntUniformName(int number);
324 const char *getFloatUniformName(int number);
325 const char *getFloatFractionUniformName(int number);
326 
327 void setupDefaultUniforms(const glu::RenderContext &context, uint32_t programID);
328 
329 } // namespace deqp
330 
331 #endif // _GLCSHADERRENDERCASE_HPP
332