blob: 08095b3c67eb83d87e773da90671ddd071787759 [file] [log] [blame] [edit]
#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 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<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);
} // 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