You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
9.0 KiB
254 lines
9.0 KiB
#ifndef _GLURENDERCONTEXT_HPP
|
|
#define _GLURENDERCONTEXT_HPP
|
|
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES Utilities
|
|
* ------------------------------------------------
|
|
*
|
|
* 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 OpenGL ES rendering context.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "tcuDefs.hpp"
|
|
|
|
// glw::GenericFuncType
|
|
#include "glwFunctionLoader.hpp"
|
|
|
|
namespace tcu
|
|
{
|
|
class CommandLine;
|
|
class Platform;
|
|
class RenderTarget;
|
|
}
|
|
|
|
namespace glw
|
|
{
|
|
class Functions;
|
|
class FunctionLoader;
|
|
}
|
|
|
|
namespace glu
|
|
{
|
|
|
|
class ContextType;
|
|
class ContextInfo;
|
|
struct RenderConfig;
|
|
|
|
enum Profile
|
|
{
|
|
PROFILE_ES = 0, //!< OpenGL ES
|
|
PROFILE_CORE, //!< OpenGL Core Profile
|
|
PROFILE_COMPATIBILITY, //!< OpenGL Compatibility Profile
|
|
|
|
PROFILE_LAST
|
|
};
|
|
|
|
enum ContextFlags
|
|
{
|
|
CONTEXT_ROBUST = (1<<0), //!< Robust context
|
|
CONTEXT_DEBUG = (1<<1), //!< Debug context
|
|
CONTEXT_FORWARD_COMPATIBLE = (1<<2), //!< Forward-compatible context
|
|
CONTEXT_NO_ERROR = (1<<3) //!< No error context
|
|
};
|
|
|
|
inline ContextFlags operator| (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a|(deUint32)b); }
|
|
inline ContextFlags operator& (ContextFlags a, ContextFlags b) { return ContextFlags((deUint32)a&(deUint32)b); }
|
|
inline ContextFlags operator~ (ContextFlags a) { return ContextFlags(~(deUint32)a); }
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Rendering API version and profile.
|
|
*//*--------------------------------------------------------------------*/
|
|
class ApiType
|
|
{
|
|
public:
|
|
ApiType (void) : m_bits(pack(0, 0, PROFILE_LAST)) {}
|
|
ApiType (int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {}
|
|
|
|
int getMajorVersion (void) const { return int((m_bits>>MAJOR_SHIFT) & ((1u<<MAJOR_BITS)-1u)); }
|
|
int getMinorVersion (void) const { return int((m_bits>>MINOR_SHIFT) & ((1u<<MINOR_BITS)-1u)); }
|
|
Profile getProfile (void) const { return Profile((m_bits>>PROFILE_SHIFT) & ((1u<<PROFILE_BITS)-1u)); }
|
|
|
|
bool operator== (ApiType other) const { return m_bits == other.m_bits; }
|
|
bool operator!= (ApiType other) const { return m_bits != other.m_bits; }
|
|
|
|
deUint32 getPacked (void) const { return m_bits; }
|
|
|
|
// Shorthands
|
|
static ApiType es (int major, int minor) { return ApiType(major, minor, PROFILE_ES); }
|
|
static ApiType core (int major, int minor) { return ApiType(major, minor, PROFILE_CORE); }
|
|
static ApiType compatibility (int major, int minor) { return ApiType(major, minor, PROFILE_COMPATIBILITY); }
|
|
|
|
protected:
|
|
ApiType (deUint32 bits) : m_bits(bits) {}
|
|
static ApiType fromBits (deUint32 bits) { return ApiType(bits); }
|
|
|
|
static deUint32 pack (int major, int minor, Profile profile);
|
|
|
|
deUint32 m_bits;
|
|
|
|
enum
|
|
{
|
|
MAJOR_BITS = 4,
|
|
MINOR_BITS = 4,
|
|
PROFILE_BITS = 2,
|
|
TOTAL_API_BITS = MAJOR_BITS+MINOR_BITS+PROFILE_BITS,
|
|
|
|
MAJOR_SHIFT = 0,
|
|
MINOR_SHIFT = MAJOR_SHIFT+MAJOR_BITS,
|
|
PROFILE_SHIFT = MINOR_SHIFT+MINOR_BITS
|
|
};
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
inline deUint32 ApiType::pack (int major, int minor, Profile profile)
|
|
{
|
|
deUint32 bits = 0;
|
|
|
|
DE_ASSERT((deUint32(major) & ~((1<<MAJOR_BITS)-1)) == 0);
|
|
DE_ASSERT((deUint32(minor) & ~((1<<MINOR_BITS)-1)) == 0);
|
|
DE_ASSERT((deUint32(profile) & ~((1<<PROFILE_BITS)-1)) == 0);
|
|
|
|
bits |= deUint32(major) << MAJOR_SHIFT;
|
|
bits |= deUint32(minor) << MINOR_SHIFT;
|
|
bits |= deUint32(profile) << PROFILE_SHIFT;
|
|
|
|
return bits;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Rendering context type.
|
|
*
|
|
* ContextType differs from API type by adding context flags. They are
|
|
* crucial in for example determining when GL core context supports
|
|
* certain API version (forward-compatible bit).
|
|
*
|
|
* \note You should NEVER compare ContextTypes against each other, as
|
|
* you most likely don't want to take flags into account. For example
|
|
* the test code almost certainly doesn't want to check that you have
|
|
* EXACTLY ES3.1 context with debug, but without for example robustness.
|
|
*//*--------------------------------------------------------------------*/
|
|
class ContextType : private ApiType
|
|
{
|
|
public:
|
|
ContextType (void) {}
|
|
ContextType (int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0));
|
|
explicit ContextType (ApiType apiType, ContextFlags flags = ContextFlags(0));
|
|
|
|
ApiType getAPI (void) const { return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u)); }
|
|
void setAPI (const ApiType& apiType) { m_bits = apiType.getPacked(); }
|
|
|
|
ContextFlags getFlags (void) const { return ContextFlags((m_bits>>FLAGS_SHIFT) & ((1u<<FLAGS_BITS)-1u)); }
|
|
|
|
using ApiType::getMajorVersion;
|
|
using ApiType::getMinorVersion;
|
|
using ApiType::getProfile;
|
|
|
|
protected:
|
|
static deUint32 pack (deUint32 apiBits, ContextFlags flags);
|
|
|
|
enum
|
|
{
|
|
FLAGS_BITS = 4,
|
|
TOTAL_CONTEXT_BITS = TOTAL_API_BITS+FLAGS_BITS,
|
|
FLAGS_SHIFT = TOTAL_API_BITS
|
|
};
|
|
} DE_WARN_UNUSED_TYPE;
|
|
|
|
inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags)
|
|
: ApiType(major, minor, profile)
|
|
{
|
|
m_bits = pack(m_bits, flags);
|
|
}
|
|
|
|
inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
|
|
: ApiType(apiType)
|
|
{
|
|
m_bits = pack(m_bits, flags);
|
|
}
|
|
|
|
inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags)
|
|
{
|
|
deUint32 bits = apiBits;
|
|
|
|
DE_ASSERT((deUint32(flags) & ~((1u<<FLAGS_BITS)-1u)) == 0);
|
|
|
|
bits |= deUint32(flags) << FLAGS_SHIFT;
|
|
|
|
return bits;
|
|
}
|
|
|
|
inline bool isContextTypeES (ContextType type) { return type.getAPI().getProfile() == PROFILE_ES; }
|
|
inline bool isContextTypeGLCore (ContextType type) { return type.getAPI().getProfile() == PROFILE_CORE; }
|
|
inline bool isContextTypeGLCompatibility(ContextType type) { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY; }
|
|
inline bool isES2Context (ContextType type) { return isContextTypeES(type) && type.getMajorVersion() == 2; }
|
|
bool contextSupports (ContextType ctxType, ApiType requiredApiType);
|
|
|
|
const char* getApiTypeDescription (ApiType type);
|
|
|
|
/*--------------------------------------------------------------------*//*!
|
|
* \brief Rendering context abstraction.
|
|
*//*--------------------------------------------------------------------*/
|
|
class RenderContext
|
|
{
|
|
public:
|
|
RenderContext (void) {}
|
|
virtual ~RenderContext (void) {}
|
|
|
|
//! Get context type. Must match to type given to ContextFactory::createContext().
|
|
virtual ContextType getType (void) const = DE_NULL;
|
|
|
|
//! Get GL function table. Should be filled with all core entry points for context type.
|
|
virtual const glw::Functions& getFunctions (void) const = DE_NULL;
|
|
|
|
//! Get render target information.
|
|
virtual const tcu::RenderTarget& getRenderTarget (void) const = DE_NULL;
|
|
|
|
//! Do post-render actions (swap buffers for example).
|
|
virtual void postIterate (void) = DE_NULL;
|
|
|
|
//! Get default framebuffer.
|
|
virtual deUint32 getDefaultFramebuffer (void) const { return 0; }
|
|
|
|
//! Get extension function address.
|
|
virtual glw::GenericFuncType getProcAddress (const char* name) const;
|
|
|
|
//! Make context current in thread. Optional to support.
|
|
virtual void makeCurrent (void);
|
|
|
|
private:
|
|
RenderContext (const RenderContext& other); // Not allowed!
|
|
RenderContext& operator= (const RenderContext& other); // Not allowed!
|
|
};
|
|
|
|
// Utilities
|
|
|
|
RenderContext* createRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, const RenderConfig& config, const RenderContext* sharedContext = DE_NULL);
|
|
RenderContext* createDefaultRenderContext (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
|
|
|
|
void initCoreFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
|
|
void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions);
|
|
|
|
// \note initFunctions() and initExtensionFunctions() without explicit extension list
|
|
// use glGetString* to query list of extensions, so it needs current GL context.
|
|
void initFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
|
|
void initExtensionFunctions (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
|
|
|
|
bool hasExtension (const glw::Functions& gl, ApiType apiType, const std::string& extension);
|
|
|
|
} // glu
|
|
|
|
#endif // _GLURENDERCONTEXT_HPP
|