| #ifndef _GLCSHADERRENDERCASE_HPP |
| #define _GLCSHADERRENDERCASE_HPP |
| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2016 Google Inc. |
| * Copyright (c) 2016 The Khronos Group Inc. |
| * |
| * 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 "glcTestCase.hpp" |
| #include "gluContextInfo.hpp" |
| #include "gluRenderContext.hpp" |
| #include "gluShaderProgram.hpp" |
| #include "tcuDefs.hpp" |
| #include "tcuMatrix.hpp" |
| #include "tcuSurface.hpp" |
| #include "tcuTexture.hpp" |
| #include "tcuVector.hpp" |
| |
| #include <sstream> |
| #include <string> |
| |
| namespace glu |
| { |
| class RenderContext; |
| class Texture2D; |
| class TextureCube; |
| class Texture2DArray; |
| class Texture3D; |
| class TextureCubeArray; |
| } // glu |
| |
| namespace deqp |
| { |
| |
| // LineStream |
| |
| 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_CUBE_MAP_ARRAY, |
| |
| 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(const glu::TextureCubeArray* texCubeArray, 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); |
| void setTexture(const glu::TextureCubeArray* texCubeArray); |
| |
| 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; |
| } |
| const glu::TextureCubeArray* getCubeArray(void) const |
| { |
| DE_ASSERT(getType() == TYPE_CUBE_MAP_ARRAY); |
| return m_binding.texCubeArray; |
| } |
| |
| 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; |
| const glu::TextureCubeArray* texCubeArray; |
| } 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; |
| const tcu::TextureCubeArray* texCubeArray; |
| |
| inline ShaderSampler(void) |
| : tex2D(DE_NULL), texCube(DE_NULL), tex2DArray(DE_NULL), tex3D(DE_NULL), texCubeArray(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 setup(deUint32 programID); |
| virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords); |
| |
| tcu::IVec2 getViewportSize(void) const; |
| |
| 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); |
| |
| } // deqp |
| |
| #endif // _GLCSHADERRENDERCASE_HPP |