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 270