Browse Source

Platform: ability to request debug context in windowless applications.

Binary AMD drivers require the user to explicitly request the debug
context on context initialization, otherwise all debug functions are
no-op. This allows us to use debug functionality in command-line utils
and, mainly, GL functionality tests.

The Windows versions are coded without testing, so I hope I did not break
something :)
pull/132/head
Vladimír Vondruš 11 years ago
parent
commit
c36573934f
  1. 13
      src/Magnum/Platform/WindowlessGlxApplication.cpp
  2. 38
      src/Magnum/Platform/WindowlessGlxApplication.h
  3. 10
      src/Magnum/Platform/WindowlessWglApplication.cpp
  4. 40
      src/Magnum/Platform/WindowlessWglApplication.h
  5. 6
      src/Magnum/Platform/WindowlessWindowsEglApplication.cpp
  6. 39
      src/Magnum/Platform/WindowlessWindowsEglApplication.h

13
src/Magnum/Platform/WindowlessGlxApplication.cpp

@ -53,7 +53,7 @@ void WindowlessGlxApplication::createContext(const Configuration& configuration)
if(!tryCreateContext(configuration)) std::exit(1);
}
bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
bool WindowlessGlxApplication::tryCreateContext(const Configuration& configuration) {
CORRADE_ASSERT(_context->version() == Version::None, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false);
_display = XOpenDisplay(nullptr);
@ -82,7 +82,7 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
};
_pbuffer = glXCreatePbuffer(_display, configs[0], pbufferAttributes);
constexpr static const GLint contextAttributes[] = {
const GLint contextAttributes[] = {
#ifdef MAGNUM_TARGET_GLES
#ifdef MAGNUM_TARGET_GLES3
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
@ -99,7 +99,7 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB|GLint(configuration.flags()),
#endif
0
};
@ -138,7 +138,12 @@ bool WindowlessGlxApplication::tryCreateContext(const Configuration&) {
glXDestroyContext(_display, _glContext);
}
_glContext = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, nullptr);
const GLint fallbackContextAttributes[] = {
GLX_CONTEXT_FLAGS_ARB, GLint(configuration.flags()),
0
};
_glContext = glXCreateContextAttribsARB(_display, configs[0], nullptr, True, fallbackContextAttributes);
}
#endif

38
src/Magnum/Platform/WindowlessGlxApplication.h

@ -30,6 +30,7 @@
*/
#include <memory>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/OpenGL.h"
#include <GL/glx.h>
@ -176,7 +177,44 @@ class WindowlessGlxApplication {
*/
class WindowlessGlxApplication::Configuration {
public:
/**
* @brief Context flag
*
* @see @ref Flags, @ref setFlags(), @ref Context::Flag
*/
enum class Flag: int {
Debug = GLX_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */
};
/**
* @brief Context flags
*
* @see @ref setFlags(), @ref Context::Flags
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, GLX_CONTEXT_DEBUG_BIT_ARB> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
constexpr /*implicit*/ Configuration() {}
/** @brief Context flags */
Flags flags() const { return _flags; }
/**
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref Context::flags().
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
private:
Flags _flags;
};
/** @hideinitializer

10
src/Magnum/Platform/WindowlessWglApplication.cpp

@ -75,7 +75,7 @@ void WindowlessWglApplication::createContext(const Configuration& configuration)
if(!tryCreateContext(configuration)) std::exit(1);
}
bool WindowlessWglApplication::tryCreateContext(const Configuration&) {
bool WindowlessWglApplication::tryCreateContext(const Configuration& configuration) {
CORRADE_ASSERT(_context->version() == Version::None, "Platform::WindowlessWglApplication::tryCreateContext(): context already created", false);
/* Get device context */
@ -104,8 +104,14 @@ bool WindowlessWglApplication::tryCreateContext(const Configuration&) {
const int pixelFormat = ChoosePixelFormat(_deviceContext, &pfd);
SetPixelFormat(_deviceContext, pixelFormat, &pfd);
const int attributes = {
WGL_CONTEXT_FLAGS_ARB, int(configuration.flags()),
0
};
/* Create context and make it current */
_renderingContext = wglCreateContext(_deviceContext);
const PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>( wglGetProcAddress(reinterpret_cast<LPCSTR>("glXCreateContextAttribsARB")));
_renderingContext = wglCreateContextAttribsARB(_deviceContext, 0, attributes);
if(!_renderingContext) {
Error() << "Platform::WindowlessWglApplication::tryCreateContext(): cannot create context:" << GetLastError();
return false;

40
src/Magnum/Platform/WindowlessWglApplication.h

@ -35,6 +35,7 @@
#define VC_EXTRALEAN
#endif
#include <windows.h>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
@ -177,7 +178,46 @@ class WindowlessWglApplication {
*/
class WindowlessWglApplication::Configuration {
public:
/**
* @brief Context flag
*
* @see @ref Flags, @ref setFlags(), @ref Context::Flag
*/
enum class Flag: int {
Debug = WGL_CONTEXT_DEBUG_BIT_ARB /**< Create debug context */
};
/**
* @brief Context flags
*
* @see @ref setFlags(), @ref Context::Flags
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, WGL_CONTEXT_DEBUG_BIT_ARB> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
#endif
constexpr /*implicit*/ Configuration() {}
~Configuration();
/** @brief Context flags */
Flags flags() const { return _flags; }
/**
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref Context::flags().
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
private:
Flags _flags;
};
/** @hideinitializer

6
src/Magnum/Platform/WindowlessWindowsEglApplication.cpp

@ -77,7 +77,7 @@ void WindowlessWindowsEglApplication::createContext(const Configuration& configu
if(!tryCreateContext(configuration)) std::exit(1);
}
bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration&) {
bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration& configuration) {
CORRADE_ASSERT(_context->version() == Version::None, "Platform::WindowlessWindowsEglApplication::tryCreateContext(): context already created", false);
/* Initialize */
@ -127,7 +127,7 @@ bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration&) {
return false;
}
static const EGLint attributes[] = {
const EGLint attributes[] = {
#ifdef MAGNUM_TARGET_GLES
EGL_CONTEXT_CLIENT_VERSION,
#ifdef MAGNUM_TARGET_GLES3
@ -138,7 +138,7 @@ bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration&) {
#error unsupported OpenGL ES version
#endif
#endif
EGL_CONTEXT_FLAGS_KHR, EGLint(configuration.flags()),
EGL_NONE
};

39
src/Magnum/Platform/WindowlessWindowsEglApplication.h

@ -36,6 +36,8 @@
#endif
#include <windows.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <Corrade/Containers/EnumSet.h>
#include "Magnum/Magnum.h"
#include "Magnum/OpenGL.h"
@ -180,7 +182,44 @@ class WindowlessWindowsEglApplication {
*/
class WindowlessWindowsEglApplication::Configuration {
public:
/**
* @brief Context flag
*
* @see @ref Flags, @ref setFlags(), @ref Context::Flag
*/
enum class Flag: int {
Debug = EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR /**< Create debug context */
};
/**
* @brief Context flags
*
* @see @ref setFlags(), @ref Context::Flags
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef Containers::EnumSet<Flag, EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR> Flags;
#else
typedef Containers::EnumSet<Flag> Flags;
#endif
constexpr /*implicit*/ Configuration() {}
/** @brief Context flags */
Flags flags() const { return _flags; }
/**
* @brief Set context flags
* @return Reference to self (for method chaining)
*
* Default is no flag. See also @ref Context::flags().
*/
Configuration& setFlags(Flags flags) {
_flags = flags;
return *this;
}
private:
Flags _flags;
};
/** @hideinitializer

Loading…
Cancel
Save