#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 namespace deqp { namespace gls { namespace LifetimeTests { namespace details { using de::MovePtr; using de::Random; using glu::CallLogWrapper; using glu::RenderContext; using std::vector; using tcu::Surface; using tcu::TestCaseGroup; using tcu::TestContext; using tcu::TestLog; 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 &getTypes(void) { return m_types; } const vector &getAttachers(void) { return m_attachers; } const vector &getInputAttachers(void) { return m_inAttachers; } const vector &getOutputAttachers(void) { return m_outAttachers; } virtual ~Types(void) { } protected: vector m_types; vector m_attachers; vector m_inAttachers; vector 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 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); } // namespace details using details::BindFunc; using details::DeleteFunc; using details::ExistsFunc; using details::GenFunc; using details::Attacher; using details::Binder; using details::Context; using details::ES2Types; using details::InputAttacher; using details::OutputAttacher; using details::SimpleBinder; using details::SimpleType; using details::Type; using details::Types; using details::addTestCases; using details::createGroup; using details::randomViewport; using details::readRectangle; using details::Rectangle; using details::setViewport; } // namespace LifetimeTests } // namespace gls } // namespace deqp #endif // _GLSLIFETIMETESTS_HPP