summaryrefslogtreecommitdiff
path: root/retrace
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2013-10-30 11:45:47 +0000
committerJosé Fonseca <jfonseca@vmware.com>2013-10-30 11:45:47 +0000
commit984010aac97b628d390dce6fecb8197eadfabb47 (patch)
tree47d243c3ac033382814db368a1de058746e5e307 /retrace
parent3ee3cd4ca0970320b0a05137cb54fc4994e0bce9 (diff)
glretrace: Support more profiles; match the profile used in glXCreateContextAttribsARBG call.
Should fix issue #176.
Diffstat (limited to 'retrace')
-rw-r--r--retrace/glretrace_glx.cpp60
-rw-r--r--retrace/glretrace_ws.cpp16
-rw-r--r--retrace/glws.cpp9
-rw-r--r--retrace/glws.hpp25
-rw-r--r--retrace/glws_cocoa.mm4
-rw-r--r--retrace/glws_egl_xlib.cpp4
-rw-r--r--retrace/glws_glx.cpp31
-rw-r--r--retrace/glws_wgl.cpp10
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;