| #ifndef _GLSSHADERRENDERCASE_HPP |
| #define _GLSSHADERRENDERCASE_HPP |
| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL (ES) Module |
| * ----------------------------------------------- |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Shader execute test. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "tcuDefs.hpp" |
| #include "tcuTestCase.hpp" |
| #include "tcuVector.hpp" |
| #include "tcuMatrix.hpp" |
| #include "tcuTexture.hpp" |
| #include "tcuSurface.hpp" |
| #include "gluRenderContext.hpp" |
| #include "gluContextInfo.hpp" |
| #include "gluShaderProgram.hpp" |
| |
| #include <sstream> |
| #include <string> |
| |
| namespace glu |
| { |
| class RenderContext; |
| class Texture2D; |
| class TextureCube; |
| class Texture2DArray; |
| class Texture3D; |
| } // glu |
| |
| namespace deqp |
| { |
| namespace gls |
| { |
| |
| // LineStream \todo [2011-10-17 pyry] Move to proper place! |
| |
| class LineStream |
| { |
| public: |
| LineStream (int indent = 0) { m_indent = indent; } |
| ~LineStream (void) {} |
| |
| const char* str (void) const { m_string = m_stream.str(); return m_string.c_str(); } |
| LineStream& operator<< (const char* line) { for (int i = 0; i < m_indent; i++) { m_stream << "\t"; } m_stream << line << "\n"; return *this; } |
| |
| private: |
| int m_indent; |
| std::ostringstream m_stream; |
| mutable std::string m_string; |
| }; |
| |
| class QuadGrid; |
| |
| // TextureBinding |
| |
| class TextureBinding |
| { |
| public: |
| enum Type |
| { |
| TYPE_NONE = 0, |
| TYPE_2D, |
| TYPE_CUBE_MAP, |
| TYPE_2D_ARRAY, |
| TYPE_3D, |
| |
| TYPE_LAST |
| }; |
| |
| TextureBinding (const glu::Texture2D* tex2D, const tcu::Sampler& sampler); |
| TextureBinding (const glu::TextureCube* texCube, const tcu::Sampler& sampler); |
| TextureBinding (const glu::Texture2DArray* tex2DArray, const tcu::Sampler& sampler); |
| TextureBinding (const glu::Texture3D* tex3D, const tcu::Sampler& sampler); |
| TextureBinding (void); |
| |
| void setSampler (const tcu::Sampler& sampler); |
| void setTexture (const glu::Texture2D* tex2D); |
| void setTexture (const glu::TextureCube* texCube); |
| void setTexture (const glu::Texture2DArray* tex2DArray); |
| void setTexture (const glu::Texture3D* tex3D); |
| |
| Type getType (void) const { return m_type; } |
| const tcu::Sampler& getSampler (void) const { return m_sampler; } |
| const glu::Texture2D* get2D (void) const { DE_ASSERT(getType() == TYPE_2D); return m_binding.tex2D; } |
| const glu::TextureCube* getCube (void) const { DE_ASSERT(getType() == TYPE_CUBE_MAP); return m_binding.texCube; } |
| const glu::Texture2DArray* get2DArray (void) const { DE_ASSERT(getType() == TYPE_2D_ARRAY); return m_binding.tex2DArray;} |
| const glu::Texture3D* get3D (void) const { DE_ASSERT(getType() == TYPE_3D); return m_binding.tex3D; } |
| |
| private: |
| Type m_type; |
| tcu::Sampler m_sampler; |
| union |
| { |
| const glu::Texture2D* tex2D; |
| const glu::TextureCube* texCube; |
| const glu::Texture2DArray* tex2DArray; |
| const glu::Texture3D* tex3D; |
| } m_binding; |
| }; |
| |
| // ShaderEvalContext. |
| |
| class ShaderEvalContext |
| { |
| public: |
| // Limits. |
| enum |
| { |
| MAX_USER_ATTRIBS = 4, |
| MAX_TEXTURES = 4, |
| }; |
| |
| struct ShaderSampler |
| { |
| tcu::Sampler sampler; |
| const tcu::Texture2D* tex2D; |
| const tcu::TextureCube* texCube; |
| const tcu::Texture2DArray* tex2DArray; |
| const tcu::Texture3D* tex3D; |
| |
| inline ShaderSampler (void) |
| : tex2D (DE_NULL) |
| , texCube (DE_NULL) |
| , tex2DArray(DE_NULL) |
| , tex3D (DE_NULL) |
| { |
| } |
| }; |
| |
| ShaderEvalContext (const QuadGrid& quadGrid); |
| ~ShaderEvalContext (void); |
| |
| void reset (float sx, float sy); |
| |
| // Inputs. |
| tcu::Vec4 coords; |
| tcu::Vec4 unitCoords; |
| tcu::Vec4 constCoords; |
| |
| tcu::Vec4 in[MAX_USER_ATTRIBS]; |
| ShaderSampler textures[MAX_TEXTURES]; |
| |
| // Output. |
| tcu::Vec4 color; |
| bool isDiscarded; |
| |
| // Functions. |
| inline void discard (void) { isDiscarded = true; } |
| tcu::Vec4 texture2D (int unitNdx, const tcu::Vec2& coords); |
| |
| private: |
| const QuadGrid& quadGrid; |
| }; |
| |
| // ShaderEvalFunc. |
| |
| typedef void (*ShaderEvalFunc) (ShaderEvalContext& c); |
| |
| inline void evalCoordsPassthroughX (ShaderEvalContext& c) { c.color.x() = c.coords.x(); } |
| inline void evalCoordsPassthroughXY (ShaderEvalContext& c) { c.color.xy() = c.coords.swizzle(0,1); } |
| inline void evalCoordsPassthroughXYZ (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); } |
| inline void evalCoordsPassthrough (ShaderEvalContext& c) { c.color = c.coords; } |
| inline void evalCoordsSwizzleWZYX (ShaderEvalContext& c) { c.color = c.coords.swizzle(3,2,1,0); } |
| |
| // ShaderEvaluator |
| // Either inherit a class with overridden evaluate() or just pass in an evalFunc. |
| |
| class ShaderEvaluator |
| { |
| public: |
| ShaderEvaluator (void); |
| ShaderEvaluator (ShaderEvalFunc evalFunc); |
| virtual ~ShaderEvaluator (void); |
| |
| virtual void evaluate (ShaderEvalContext& ctx); |
| |
| private: |
| ShaderEvaluator (const ShaderEvaluator&); // not allowed! |
| ShaderEvaluator& operator= (const ShaderEvaluator&); // not allowed! |
| |
| ShaderEvalFunc m_evalFunc; |
| }; |
| |
| // ShaderRenderCase. |
| |
| class ShaderRenderCase : public tcu::TestCase |
| { |
| public: |
| ShaderRenderCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc); |
| ShaderRenderCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, bool isVertexCase, ShaderEvaluator& evaluator); |
| virtual ~ShaderRenderCase (void); |
| |
| void init (void); |
| void deinit (void); |
| |
| IterateResult iterate (void); |
| |
| protected: |
| virtual void setupShaderData (void); |
| virtual void setup (int programID); |
| virtual void setupUniforms (int programID, const tcu::Vec4& constCoords); |
| |
| tcu::IVec2 getViewportSize (void) const; |
| |
| class CompileFailed : public tcu::TestError |
| { |
| public: |
| inline CompileFailed (const char* file, int line) : tcu::TestError("Failed to compile shader program", DE_NULL, file, line) {} |
| }; |
| |
| private: |
| ShaderRenderCase (const ShaderRenderCase&); // not allowed! |
| ShaderRenderCase& operator= (const ShaderRenderCase&); // not allowed! |
| |
| void setupDefaultInputs (int programID); |
| |
| void render (tcu::Surface& result, int programID, const QuadGrid& quadGrid); |
| void computeVertexReference (tcu::Surface& result, const QuadGrid& quadGrid); |
| void computeFragmentReference(tcu::Surface& result, const QuadGrid& quadGrid); |
| bool compareImages (const tcu::Surface& resImage, const tcu::Surface& refImage, float errorThreshold); |
| |
| protected: |
| glu::RenderContext& m_renderCtx; |
| const glu::ContextInfo& m_ctxInfo; |
| |
| bool m_isVertexCase; |
| ShaderEvaluator m_defaultEvaluator; |
| ShaderEvaluator& m_evaluator; |
| std::string m_vertShaderSource; |
| std::string m_fragShaderSource; |
| tcu::Vec4 m_clearColor; |
| |
| std::vector<tcu::Mat4> m_userAttribTransforms; |
| std::vector<TextureBinding> m_textures; |
| |
| glu::ShaderProgram* m_program; |
| }; |
| |
| // Helpers. |
| // \todo [2012-04-10 pyry] Move these to separate utility? |
| |
| const char* getIntUniformName (int number); |
| const char* getFloatUniformName (int number); |
| const char* getFloatFractionUniformName (int number); |
| |
| void setupDefaultUniforms (const glu::RenderContext& context, deUint32 programID); |
| |
| } // gls |
| } // deqp |
| |
| #endif // _GLSSHADERRENDERCASE_HPP |