| #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; |
| } // namespace 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; |
| int m_gridSize; |
| }; |
| |
| // 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, uint32_t programID); |
| |
| } // namespace gls |
| } // namespace deqp |
| |
| #endif // _GLSSHADERRENDERCASE_HPP |