#ifndef _GLSLIFETIMETESTS_HPP #define _GLSLIFETIMETESTS_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 Common object lifetime tests. *//*--------------------------------------------------------------------*/ #include "deRandom.hpp" #include "deUniquePtr.hpp" #include "tcuSurface.hpp" #include "tcuTestCase.hpp" #include "tcuTestContext.hpp" #include "gluCallLogWrapper.hpp" #include "gluRenderContext.hpp" #include "glwDefs.hpp" #include "glwEnums.hpp" #include <vector> namespace deqp { namespace gls { namespace LifetimeTests { namespace details { using std::vector; using de::MovePtr; using de::Random; using tcu::Surface; using tcu::TestCaseGroup; using tcu::TestContext; using tcu::TestLog; using glu::CallLogWrapper; using glu::RenderContext; using namespace glw; typedef void (CallLogWrapper::*BindFunc) (GLenum target, GLuint name); typedef void (CallLogWrapper::*GenFunc) (GLsizei n, GLuint* names); typedef void (CallLogWrapper::*DeleteFunc) (GLsizei n, const GLuint* names); typedef GLboolean (CallLogWrapper::*ExistsFunc) (GLuint name); class Context { public: Context (const RenderContext& renderCtx, TestContext& testCtx) : m_renderCtx (renderCtx) , m_testCtx (testCtx) {} const RenderContext& getRenderContext (void) const { return m_renderCtx; } TestContext& getTestContext (void) const { return m_testCtx; } const Functions& gl (void) const { return m_renderCtx.getFunctions(); } TestLog& log (void) const { return m_testCtx.getLog(); } private: const RenderContext& m_renderCtx; TestContext& m_testCtx; }; class ContextWrapper : public CallLogWrapper { public: const Context& getContext (void) const { return m_ctx; } const RenderContext& getRenderContext (void) const { return m_ctx.getRenderContext(); } TestContext& getTestContext (void) const { return m_ctx.getTestContext(); } const Functions& gl (void) const { return m_ctx.gl(); } TestLog& log (void) const { return m_ctx.log(); } void enableLogging (bool enable) { CallLogWrapper::enableLogging(enable); } protected: ContextWrapper (const Context& ctx); const Context m_ctx; }; class Binder : public ContextWrapper { public: virtual ~Binder (void) {} virtual void bind (GLuint name) = 0; virtual GLuint getBinding (void) = 0; virtual bool genRequired (void) const { return true; } protected: Binder (const Context& ctx) : ContextWrapper(ctx) {} }; class SimpleBinder : public Binder { public: SimpleBinder (const Context& ctx, BindFunc bindFunc, GLenum bindTarget, GLenum bindingParam, bool genRequired_ = false) : Binder (ctx) , m_bindFunc (bindFunc) , m_bindTarget (bindTarget) , m_bindingParam (bindingParam) , m_genRequired (genRequired_) {} void bind (GLuint name); GLuint getBinding (void); bool genRequired (void) const { return m_genRequired; } private: const BindFunc m_bindFunc; const GLenum m_bindTarget; const GLenum m_bindingParam; const bool m_genRequired; }; class Type : public ContextWrapper { public: virtual ~Type (void) {} virtual GLuint gen (void) = 0; virtual void release (GLuint name) = 0; virtual bool exists (GLuint name) = 0; virtual bool isDeleteFlagged (GLuint name) { DE_UNREF(name); return false; } virtual Binder* binder (void) const { return DE_NULL; } virtual const char* getName (void) const = 0; virtual bool nameLingers (void) const { return false; } virtual bool genCreates (void) const { return false; } protected: Type (const Context& ctx) : ContextWrapper(ctx) {} }; class SimpleType : public Type { public: SimpleType (const Context& ctx, const char* name, GenFunc genFunc, DeleteFunc deleteFunc, ExistsFunc existsFunc, Binder* binder_ = DE_NULL, bool genCreates_ = false) : Type (ctx) , m_getName (name) , m_genFunc (genFunc) , m_deleteFunc (deleteFunc) , m_existsFunc (existsFunc) , m_binder (binder_) , m_genCreates (genCreates_) {} GLuint gen (void); void release (GLuint name) { (this->*m_deleteFunc)(1, &name); } bool exists (GLuint name) { return (this->*m_existsFunc)(name) != GL_FALSE; } Binder* binder (void) const { return m_binder; } const char* getName (void) const { return m_getName; } bool nameLingers (void) const { return false; } bool genCreates (void) const { return m_genCreates; } private: const char* const m_getName; const GenFunc m_genFunc; const DeleteFunc m_deleteFunc; const ExistsFunc m_existsFunc; Binder* const m_binder; const bool m_genCreates; }; class ProgramType : public Type { public: ProgramType (const Context& ctx) : Type(ctx) {} bool nameLingers (void) const { return true; } bool genCreates (void) const { return true; } const char* getName (void) const { return "program"; } GLuint gen (void) { return glCreateProgram(); } void release (GLuint name) { glDeleteProgram(name); } bool exists (GLuint name) { return glIsProgram(name) != GL_FALSE; } bool isDeleteFlagged (GLuint name); }; class ShaderType : public Type { public: ShaderType (const Context& ctx) : Type(ctx) {} bool nameLingers (void) const { return true; } bool genCreates (void) const { return true; } const char* getName (void) const { return "shader"; } GLuint gen (void) { return glCreateShader(GL_FRAGMENT_SHADER); } void release (GLuint name) { glDeleteShader(name); } bool exists (GLuint name) { return glIsShader(name) != GL_FALSE; } bool isDeleteFlagged (GLuint name); }; class Attacher : public ContextWrapper { public: virtual void initAttachment (GLuint seed, GLuint attachment) = 0; virtual void attach (GLuint element, GLuint container) = 0; virtual void detach (GLuint element, GLuint container) = 0; virtual GLuint getAttachment (GLuint container) = 0; virtual bool canAttachDeleted (void) const { return true; } Type& getElementType (void) const { return m_elementType; } Type& getContainerType (void) const { return m_containerType; } virtual ~Attacher (void) {} protected: Attacher (const Context& ctx, Type& elementType, Type& containerType) : ContextWrapper (ctx) , m_elementType (elementType) , m_containerType (containerType) {} private: Type& m_elementType; Type& m_containerType; }; class InputAttacher : public ContextWrapper { public: Attacher& getAttacher (void) const { return m_attacher; } virtual void drawContainer (GLuint container, Surface& dst) = 0; protected: InputAttacher (Attacher& attacher) : ContextWrapper (attacher.getContext()) , m_attacher (attacher) {} Attacher& m_attacher; }; class OutputAttacher : public ContextWrapper { public: Attacher& getAttacher (void) const { return m_attacher; } virtual void setupContainer (GLuint seed, GLuint container) = 0; virtual void drawAttachment (GLuint attachment, Surface& dst) = 0; protected: OutputAttacher (Attacher& attacher) : ContextWrapper (attacher.getContext()) , m_attacher (attacher) {} Attacher& m_attacher; }; class Types : public ContextWrapper { public: Types (const Context& ctx) : ContextWrapper(ctx) {} virtual Type& getProgramType (void) = 0; const vector<Type*>& getTypes (void) { return m_types; } const vector<Attacher*>& getAttachers (void) { return m_attachers; } const vector<InputAttacher*>& getInputAttachers (void) { return m_inAttachers; } const vector<OutputAttacher*>& getOutputAttachers (void) { return m_outAttachers; } virtual ~Types (void) {} protected: vector<Type*> m_types; vector<Attacher*> m_attachers; vector<InputAttacher*> m_inAttachers; vector<OutputAttacher*> m_outAttachers; }; class FboAttacher : public Attacher { public: void initAttachment (GLuint seed, GLuint element); protected: FboAttacher (const Context& ctx, Type& elementType, Type& containerType) : Attacher (ctx, elementType, containerType) {} virtual void initStorage (void) = 0; }; class FboInputAttacher : public InputAttacher { public: FboInputAttacher (FboAttacher& attacher) : InputAttacher (attacher) {} void drawContainer (GLuint container, Surface& dst); }; class FboOutputAttacher : public OutputAttacher { public: FboOutputAttacher (FboAttacher& attacher) : OutputAttacher (attacher) {} void setupContainer (GLuint seed, GLuint container); void drawAttachment (GLuint attachment, Surface& dst); }; class TextureFboAttacher : public FboAttacher { public: TextureFboAttacher (const Context& ctx, Type& elementType, Type& containerType) : FboAttacher (ctx, elementType, containerType) {} void initStorage (void); void attach (GLuint element, GLuint container); void detach (GLuint element, GLuint container); GLuint getAttachment (GLuint container); }; class RboFboAttacher : public FboAttacher { public: RboFboAttacher (const Context& ctx, Type& elementType, Type& containerType) : FboAttacher (ctx, elementType, containerType) {} void initStorage (void); void attach (GLuint element, GLuint container); void detach (GLuint element, GLuint container); GLuint getAttachment (GLuint container); }; class ShaderProgramAttacher : public Attacher { public: ShaderProgramAttacher (const Context& ctx, Type& elementType, Type& containerType) : Attacher (ctx, elementType, containerType) {} void initAttachment (GLuint seed, GLuint element); void attach (GLuint element, GLuint container); void detach (GLuint element, GLuint container); GLuint getAttachment (GLuint container); }; class ShaderProgramInputAttacher : public InputAttacher { public: ShaderProgramInputAttacher (Attacher& attacher) : InputAttacher (attacher) {} void drawContainer (GLuint container, Surface& dst); }; class ES2Types : public Types { public: ES2Types (const Context& ctx); Type& getProgramType (void) { return m_programType; } protected: SimpleBinder m_bufferBind; SimpleType m_bufferType; SimpleBinder m_textureBind; SimpleType m_textureType; SimpleBinder m_rboBind; SimpleType m_rboType; SimpleBinder m_fboBind; SimpleType m_fboType; ShaderType m_shaderType; ProgramType m_programType; TextureFboAttacher m_texFboAtt; FboInputAttacher m_texFboInAtt; FboOutputAttacher m_texFboOutAtt; RboFboAttacher m_rboFboAtt; FboInputAttacher m_rboFboInAtt; FboOutputAttacher m_rboFboOutAtt; ShaderProgramAttacher m_shaderAtt; ShaderProgramInputAttacher m_shaderInAtt; }; MovePtr<TestCaseGroup> createGroup (TestContext& testCtx, Type& type); void addTestCases (TestCaseGroup& group, Types& types); struct Rectangle { Rectangle (GLint x_, GLint y_, GLint width_, GLint height_) : x (x_) , y (y_) , width (width_) , height (height_) {} GLint x; GLint y; GLint width; GLint height; }; Rectangle randomViewport (const RenderContext& ctx, GLint maxWidth, GLint maxHeight, Random& rnd); void setViewport (const RenderContext& renderCtx, const Rectangle& rect); void readRectangle (const RenderContext& renderCtx, const Rectangle& rect, Surface& dst); } // details using details::BindFunc; using details::GenFunc; using details::DeleteFunc; using details::ExistsFunc; using details::Context; using details::Binder; using details::SimpleBinder; using details::Type; using details::SimpleType; using details::Attacher; using details::InputAttacher; using details::OutputAttacher; using details::Types; using details::ES2Types; using details::createGroup; using details::addTestCases; using details::Rectangle; using details::randomViewport; using details::setViewport; using details::readRectangle; } // LifetimeTests } // gls } // deqp #endif // _GLSLIFETIMETESTS_HPP