Do not use degenerate frames in EGL tests
[platform/upstream/VK-GL-CTS.git] / modules / glshared / glsShaderRenderCase.hpp
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 } // 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:
58                                                 LineStream              (int indent = 0)        { m_indent = indent; }
59                                                 ~LineStream             (void)                          {}
60
61         const char*                     str                             (void) const            { m_string = m_stream.str(); return m_string.c_str(); }
62         LineStream&                     operator<<              (const char* line)      { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; }
63
64 private:
65         int                                     m_indent;
66         std::ostringstream      m_stream;
67         mutable std::string     m_string;
68 };
69
70 class QuadGrid;
71
72 // TextureBinding
73
74 class TextureBinding
75 {
76 public:
77         enum Type
78         {
79                 TYPE_NONE = 0,
80                 TYPE_2D,
81                 TYPE_CUBE_MAP,
82                 TYPE_2D_ARRAY,
83                 TYPE_3D,
84
85                 TYPE_LAST
86         };
87
88                                                                 TextureBinding          (const glu::Texture2D* tex2D, const tcu::Sampler& sampler);
89                                                                 TextureBinding          (const glu::TextureCube* texCube, const tcu::Sampler& sampler);
90                                                                 TextureBinding          (const glu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler);
91                                                                 TextureBinding          (const glu::Texture3D* tex3D, const tcu::Sampler& sampler);
92                                                                 TextureBinding          (void);
93
94         void                                            setSampler                      (const tcu::Sampler& sampler);
95         void                                            setTexture                      (const glu::Texture2D* tex2D);
96         void                                            setTexture                      (const glu::TextureCube* texCube);
97         void                                            setTexture                      (const glu::Texture2DArray* tex2DArray);
98         void                                            setTexture                      (const glu::Texture3D* tex3D);
99
100         Type                                            getType                         (void) const { return m_type;           }
101         const tcu::Sampler&                     getSampler                      (void) const { return m_sampler;        }
102         const glu::Texture2D*           get2D                           (void) const { DE_ASSERT(getType() == TYPE_2D);                 return m_binding.tex2D;         }
103         const glu::TextureCube*         getCube                         (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP);   return m_binding.texCube;       }
104         const glu::Texture2DArray*      get2DArray                      (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY);   return m_binding.tex2DArray;}
105         const glu::Texture3D*           get3D                           (void) const { DE_ASSERT(getType() == TYPE_3D);                 return m_binding.tex3D;         }
106
107 private:
108         Type                                    m_type;
109         tcu::Sampler                    m_sampler;
110         union
111         {
112                 const glu::Texture2D*           tex2D;
113                 const glu::TextureCube*         texCube;
114                 const glu::Texture2DArray*      tex2DArray;
115                 const glu::Texture3D*           tex3D;
116         } m_binding;
117 };
118
119 // ShaderEvalContext.
120
121 class ShaderEvalContext
122 {
123 public:
124         // Limits.
125         enum
126         {
127                 MAX_USER_ATTRIBS        = 4,
128                 MAX_TEXTURES            = 4,
129         };
130
131         struct ShaderSampler
132         {
133                 tcu::Sampler                            sampler;
134                 const tcu::Texture2D*           tex2D;
135                 const tcu::TextureCube*         texCube;
136                 const tcu::Texture2DArray*      tex2DArray;
137                 const tcu::Texture3D*           tex3D;
138
139                 inline ShaderSampler (void)
140                         : tex2D         (DE_NULL)
141                         , texCube       (DE_NULL)
142                         , tex2DArray(DE_NULL)
143                         , tex3D         (DE_NULL)
144                 {
145                 }
146         };
147
148                                                         ShaderEvalContext               (const QuadGrid& quadGrid);
149                                                         ~ShaderEvalContext              (void);
150
151         void                                    reset                                   (float sx, float sy);
152
153         // Inputs.
154         tcu::Vec4                               coords;
155         tcu::Vec4                               unitCoords;
156         tcu::Vec4                               constCoords;
157
158         tcu::Vec4                               in[MAX_USER_ATTRIBS];
159         ShaderSampler                   textures[MAX_TEXTURES];
160
161         // Output.
162         tcu::Vec4                               color;
163         bool                                    isDiscarded;
164
165         // Functions.
166         inline void                             discard                                 (void)  { isDiscarded = true; }
167         tcu::Vec4                               texture2D                               (int unitNdx, const tcu::Vec2& coords);
168
169 private:
170         const QuadGrid&                 quadGrid;
171 };
172
173 // ShaderEvalFunc.
174
175 typedef void (*ShaderEvalFunc) (ShaderEvalContext& c);
176
177 inline void evalCoordsPassthroughX              (ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
178 inline void evalCoordsPassthroughXY             (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
179 inline void evalCoordsPassthroughXYZ    (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
180 inline void evalCoordsPassthrough               (ShaderEvalContext& c) { c.color = c.coords; }
181 inline void evalCoordsSwizzleWZYX               (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); }
182
183 // ShaderEvaluator
184 // Either inherit a class with overridden evaluate() or just pass in an evalFunc.
185
186 class ShaderEvaluator
187 {
188 public:
189                                                 ShaderEvaluator                 (void);
190                                                 ShaderEvaluator                 (ShaderEvalFunc evalFunc);
191         virtual                         ~ShaderEvaluator                (void);
192
193         virtual void            evaluate                                (ShaderEvalContext& ctx);
194
195 private:
196                                                 ShaderEvaluator                 (const ShaderEvaluator&);       // not allowed!
197         ShaderEvaluator&        operator=                               (const ShaderEvaluator&);       // not allowed!
198
199         ShaderEvalFunc          m_evalFunc;
200 };
201
202 // ShaderRenderCase.
203
204 class ShaderRenderCase : public tcu::TestCase
205 {
206 public:
207                                                                 ShaderRenderCase                (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc);
208                                                                 ShaderRenderCase                (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvaluator& evaluator);
209         virtual                                         ~ShaderRenderCase               (void);
210
211         void                                            init                                    (void);
212         void                                            deinit                                  (void);
213
214         IterateResult                           iterate                                 (void);
215
216 protected:
217         virtual void                            setupShaderData                 (void);
218         virtual void                            setup                                   (int programID);
219         virtual void                            setupUniforms                   (int programID, const tcu::Vec4& constCoords);
220
221         tcu::IVec2                                      getViewportSize                 (void) const;
222
223         class CompileFailed : public tcu::TestError
224         {
225         public:
226                 inline CompileFailed (const char* file, int line) : tcu::TestError("Failed to compile shader program", DE_NULL, file, line) {}
227         };
228
229 private:
230                                                                 ShaderRenderCase                (const ShaderRenderCase&);              // not allowed!
231         ShaderRenderCase&                       operator=                               (const ShaderRenderCase&);              // not allowed!
232
233         void                                            setupDefaultInputs              (int programID);
234
235         void                                            render                                  (tcu::Surface& result, int programID, const QuadGrid& quadGrid);
236         void                                            computeVertexReference  (tcu::Surface& result, const QuadGrid& quadGrid);
237         void                                            computeFragmentReference(tcu::Surface& result, const QuadGrid& quadGrid);
238         bool                                            compareImages                   (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold);
239
240 protected:
241         glu::RenderContext&                     m_renderCtx;
242         const glu::ContextInfo&         m_ctxInfo;
243
244         bool                                            m_isVertexCase;
245         ShaderEvaluator                         m_defaultEvaluator;
246         ShaderEvaluator&                        m_evaluator;
247         std::string                                     m_vertShaderSource;
248         std::string                                     m_fragShaderSource;
249         tcu::Vec4                                       m_clearColor;
250
251         std::vector<tcu::Mat4>          m_userAttribTransforms;
252         std::vector<TextureBinding>     m_textures;
253
254         glu::ShaderProgram*                     m_program;
255 };
256
257 // Helpers.
258 // \todo [2012-04-10 pyry] Move these to separate utility?
259
260 const char*             getIntUniformName                       (int number);
261 const char*             getFloatUniformName                     (int number);
262 const char*             getFloatFractionUniformName     (int number);
263
264 void                    setupDefaultUniforms            (const glu::RenderContext& context, deUint32 programID);
265
266 } // gls
267 } // deqp
268
269 #endif // _GLSSHADERRENDERCASE_HPP