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:
LineStream(int indent=0)58 LineStream (int indent = 0) { m_indent = indent; }
~LineStream(void)59 ~LineStream (void) {}
60
str(void) const61 const char* str (void) const { m_string = m_stream.str(); return m_string.c_str(); }
operator <<(const char * line)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
getType(void) const100 Type getType (void) const { return m_type; }
getSampler(void) const101 const tcu::Sampler& getSampler (void) const { return m_sampler; }
get2D(void) const102 const glu::Texture2D* get2D (void) const { DE_ASSERT(getType() == TYPE_2D); return m_binding.tex2D; }
getCube(void) const103 const glu::TextureCube* getCube (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP); return m_binding.texCube; }
get2DArray(void) const104 const glu::Texture2DArray* get2DArray (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY); return m_binding.tex2DArray;}
get3D(void) const105 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
ShaderSamplerdeqp::gls::ShaderEvalContext::ShaderSampler139 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.
discard(void)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
evalCoordsPassthroughX(ShaderEvalContext & c)177 inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); }
evalCoordsPassthroughXY(ShaderEvalContext & c)178 inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); }
evalCoordsPassthroughXYZ(ShaderEvalContext & c)179 inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
evalCoordsPassthrough(ShaderEvalContext & c)180 inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; }
evalCoordsSwizzleWZYX(ShaderEvalContext & c)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:
CompileFailed(const char * file,int line)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
270