blob: f345bae362e20d362d4f9cdfb99179caf4a41922 [file] [log] [blame]
#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