| #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 |