diff options
author | José Fonseca <jfonseca@vmware.com> | 2013-10-30 11:45:47 +0000 |
---|---|---|
committer | José Fonseca <jfonseca@vmware.com> | 2013-10-30 11:45:47 +0000 |
commit | 984010aac97b628d390dce6fecb8197eadfabb47 (patch) | |
tree | 47d243c3ac033382814db368a1de058746e5e307 | |
parent | 3ee3cd4ca0970320b0a05137cb54fc4994e0bce9 (diff) |
glretrace: Support more profiles; match the profile used in glXCreateContextAttribsARBG call.
Should fix issue #176.
-rw-r--r-- | retrace/glretrace_glx.cpp | 60 | ||||
-rw-r--r-- | retrace/glretrace_ws.cpp | 16 | ||||
-rw-r--r-- | retrace/glws.cpp | 9 | ||||
-rw-r--r-- | retrace/glws.hpp | 25 | ||||
-rw-r--r-- | retrace/glws_cocoa.mm | 4 | ||||
-rw-r--r-- | retrace/glws_egl_xlib.cpp | 4 | ||||
-rw-r--r-- | retrace/glws_glx.cpp | 31 | ||||
-rw-r--r-- | retrace/glws_wgl.cpp | 10 |
8 files changed, 112 insertions, 47 deletions
diff --git a/retrace/glretrace_glx.cpp b/retrace/glretrace_glx.cpp index 7efc3bf3..93ad47bd 100644 --- a/retrace/glretrace_glx.cpp +++ b/retrace/glretrace_glx.cpp @@ -28,14 +28,23 @@ #include "retrace.hpp" #include "glretrace.hpp" +#if !defined(HAVE_X11) -#ifndef GLX_PBUFFER_HEIGHT #define GLX_PBUFFER_HEIGHT 0x8040 -#endif - -#ifndef GLX_PBUFFER_WIDTH #define GLX_PBUFFER_WIDTH 0x8041 -#endif + +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 + +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 + +#endif /* !HAVE_X11 */ using namespace glretrace; @@ -89,7 +98,46 @@ static void retrace_glXCreateContextAttribsARB(trace::Call &call) { unsigned long long orig_context = call.ret->toUIntPtr(); Context *share_context = getContext(call.arg(2).toUIntPtr()); - Context *context = glretrace::createContext(share_context); + unsigned major = 1; + unsigned minor = 0; + bool core = false; + + const trace::Array * attribs = call.arg(4).toArray(); + if (attribs) { + size_t i = 0; + while (i < attribs->values.size()) { + int param = attribs->values[i++]->toSInt(); + if (param == 0) { + break; + } + int value = attribs->values[i++]->toSInt(); + + switch (param) { + case GLX_CONTEXT_MAJOR_VERSION_ARB: + major = value; + break; + case GLX_CONTEXT_MINOR_VERSION_ARB: + minor = value; + break; + case GLX_CONTEXT_FLAGS_ARB: + break; + case GLX_CONTEXT_PROFILE_MASK_ARB: + if (value & GLX_CONTEXT_CORE_PROFILE_BIT_ARB) { + core = true; + } + break; + default: + break; + } + } + } + + glws::Profile profile = glws::PROFILE_COMPAT; + if (major >= 3) { + profile = (glws::Profile)((core ? 0x100 : 0) | (major << 4) | minor); + } + + Context *context = glretrace::createContext(share_context, profile); context_map[orig_context] = context; } diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp index a69c2cff..53e0710d 100644 --- a/retrace/glretrace_ws.cpp +++ b/retrace/glretrace_ws.cpp @@ -31,6 +31,8 @@ #include <string.h> +#include <map> + #include "os_thread.hpp" #include "retrace.hpp" #include "glproc.hpp" @@ -41,21 +43,23 @@ namespace glretrace { -static glws::Visual * -visuals[glws::PROFILE_MAX]; +static std::map<glws::Profile, glws::Visual *> +visuals; inline glws::Visual * getVisual(glws::Profile profile) { - glws::Visual * & visual = visuals[profile]; - if (!visual) { - visual = glws::createVisual(retrace::doubleBuffer, profile); + std::map<glws::Profile, glws::Visual *>::iterator it = visuals.find(profile); + if (it == visuals.end()) { + glws::Visual *visual = glws::createVisual(retrace::doubleBuffer, profile); if (!visual) { std::cerr << "error: failed to create OpenGL visual\n"; exit(1); } + visuals[profile] = visual; + return visual; } - return visual; + return it->second; } diff --git a/retrace/glws.cpp b/retrace/glws.cpp index e8ea0d16..44ba8876 100644 --- a/retrace/glws.cpp +++ b/retrace/glws.cpp @@ -35,6 +35,15 @@ namespace glws { +void +getProfileVersion(Profile profile, unsigned &major, unsigned &minor, bool &core) +{ + major = (profile >> 4) & 0xf; + minor = profile & 0xf; + core = isCoreProfile(profile); +} + + bool checkExtension(const char *extName, const char *extString) { diff --git a/retrace/glws.hpp b/retrace/glws.hpp index 2e03aa67..d6d1a9f3 100644 --- a/retrace/glws.hpp +++ b/retrace/glws.hpp @@ -42,21 +42,32 @@ namespace glws { enum Profile { - PROFILE_COMPAT = 0, - PROFILE_3_2_CORE, - PROFILE_4_1_CORE, - PROFILE_ES1, - PROFILE_ES2, + PROFILE_COMPAT = 0x000, + PROFILE_3_0 = 0x030, + PROFILE_3_1 = 0x031, + PROFILE_3_2_CORE = 0x132, + PROFILE_3_3_CORE = 0x133, + PROFILE_4_0_CORE = 0x140, + PROFILE_4_1_CORE = 0x141, + PROFILE_4_2_CORE = 0x142, + PROFILE_4_3_CORE = 0x143, + PROFILE_4_4_CORE = 0x144, + PROFILE_ES1 = 0x210, + PROFILE_ES2 = 0x220, PROFILE_MAX }; static inline bool isCoreProfile(Profile profile) { - return profile == PROFILE_3_2_CORE || - profile == PROFILE_4_1_CORE; + return (profile & 0x100) == 0x100; } + +void +getProfileVersion(Profile profile, unsigned &major, unsigned &minor, bool &core); + + bool checkExtension(const char *extName, const char *extString); diff --git a/retrace/glws_cocoa.mm b/retrace/glws_cocoa.mm index 9c0f1dfb..8be94189 100644 --- a/retrace/glws_cocoa.mm +++ b/retrace/glws_cocoa.mm @@ -237,11 +237,15 @@ createVisual(bool doubleBuffer, Profile profile) { case PROFILE_COMPAT: break; #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 + case PROFILE_3_0: + case PROFILE_3_1: case PROFILE_3_2_CORE: attribs.add(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); break; #endif #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 + case PROFILE_3_3_CORE: + case PROFILE_4_0_CORE: case PROFILE_4_1_CORE: attribs.add(NSOpenGLPFAOpenGLProfile, kCGLOGLPVersion_GL4_Core); break; diff --git a/retrace/glws_egl_xlib.cpp b/retrace/glws_egl_xlib.cpp index 125d5f4f..90683a83 100644 --- a/retrace/glws_egl_xlib.cpp +++ b/retrace/glws_egl_xlib.cpp @@ -420,10 +420,6 @@ createContext(const Visual *_visual, Context *shareContext, bool debug) load("libGL.so.1"); eglBindAPI(EGL_OPENGL_API); break; - case PROFILE_3_2_CORE: - case PROFILE_4_1_CORE: - assert(0); - return NULL; case PROFILE_ES1: load("libGLESv1_CM.so.1"); eglBindAPI(EGL_OPENGL_ES_API); diff --git a/retrace/glws_glx.cpp b/retrace/glws_glx.cpp index 9f241fa1..0b4261b9 100644 --- a/retrace/glws_glx.cpp +++ b/retrace/glws_glx.cpp @@ -273,13 +273,6 @@ cleanup(void) { Visual * createVisual(bool doubleBuffer, Profile profile) { - if (profile != PROFILE_COMPAT && - profile != PROFILE_3_2_CORE && - profile != PROFILE_4_1_CORE && - profile != PROFILE_ES2) { - return NULL; - } - GlxVisual *visual = new GlxVisual(profile); if (glxVersion >= 0x0103) { @@ -352,21 +345,23 @@ createContext(const Visual *_visual, Context *shareContext, bool debug) switch (profile) { case PROFILE_COMPAT: break; + case PROFILE_ES1: + return NULL; case PROFILE_ES2: attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT); break; - case PROFILE_3_2_CORE: - attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, 3); - attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, 2); - attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB); - break; - case PROFILE_4_1_CORE: - attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, 4); - attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, 1); - attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB); - break; default: - return NULL; + { + unsigned major, minor; + bool core; + getProfileVersion(profile, major, minor, core); + attribs.add(GLX_CONTEXT_MAJOR_VERSION_ARB, major); + attribs.add(GLX_CONTEXT_MINOR_VERSION_ARB, minor); + if (core) { + attribs.add(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB); + } + break; + } } attribs.end(); diff --git a/retrace/glws_wgl.cpp b/retrace/glws_wgl.cpp index d7c6cda8..bc187ce2 100644 --- a/retrace/glws_wgl.cpp +++ b/retrace/glws_wgl.cpp @@ -306,18 +306,16 @@ createVisual(bool doubleBuffer, Profile profile) { switch (profile) { case PROFILE_COMPAT: break; - case PROFILE_3_2_CORE: - case PROFILE_4_1_CORE: - std::cerr << "warning: ignoring OpenGL core profile request\n"; - break; + case PROFILE_ES1: + return NULL; case PROFILE_ES2: std::cerr << "warning: ignoring OpenGL ES 2.0 profile request\n"; break; default: - return NULL; + std::cerr << "warning: ignoring OpenGL profile request\n"; + break; } - Visual *visual = new Visual(profile); visual->doubleBuffer = doubleBuffer; |