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 39namespace glu 40{ 41class RenderContext; 42class Texture2D; 43class TextureCube; 44class Texture2DArray; 45class Texture3D; 46} // glu 47 48namespace deqp 49{ 50namespace gls 51{ 52 53// LineStream \todo [2011-10-17 pyry] Move to proper place! 54 55class LineStream 56{ 57public: 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 64private: 65 int m_indent; 66 std::ostringstream m_stream; 67 mutable std::string m_string; 68}; 69 70class QuadGrid; 71 72// TextureBinding 73 74class TextureBinding 75{ 76public: 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 107private: 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 121class ShaderEvalContext 122{ 123public: 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 169private: 170 const QuadGrid& quadGrid; 171}; 172 173// ShaderEvalFunc. 174 175typedef void (*ShaderEvalFunc) (ShaderEvalContext& c); 176 177inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); } 178inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); } 179inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); } 180inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; } 181inline 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 186class ShaderEvaluator 187{ 188public: 189 ShaderEvaluator (void); 190 ShaderEvaluator (ShaderEvalFunc evalFunc); 191 virtual ~ShaderEvaluator (void); 192 193 virtual void evaluate (ShaderEvalContext& ctx); 194 195private: 196 ShaderEvaluator (const ShaderEvaluator&); // not allowed! 197 ShaderEvaluator& operator= (const ShaderEvaluator&); // not allowed! 198 199 ShaderEvalFunc m_evalFunc; 200}; 201 202// ShaderRenderCase. 203 204class ShaderRenderCase : public tcu::TestCase 205{ 206public: 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 216protected: 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 229private: 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 240protected: 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 260const char* getIntUniformName (int number); 261const char* getFloatUniformName (int number); 262const char* getFloatFractionUniformName (int number); 263 264void setupDefaultUniforms (const glu::RenderContext& context, deUint32 programID); 265 266} // gls 267} // deqp 268 269#endif // _GLSSHADERRENDERCASE_HPP 270