mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Support OpenGL debugging features (see gl-debug).
Also fixed the GLX code not to call reset() on the temp context but on the real context instead.
This commit is contained in:
parent
ef9f985406
commit
128f82863e
@ -337,6 +337,49 @@ CLP(GraphicsStateGuardian)::
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::debug_callback
|
||||
// Access: Public, Static
|
||||
// Description: This is called by the GL if an error occurs, if
|
||||
// gl_debug has been enabled (and the driver supports
|
||||
// the GL_ARB_debug_output extension).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) {
|
||||
// Determine how to map the severity level.
|
||||
NotifySeverity level;
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_HIGH:
|
||||
level = NS_error;
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||
level = NS_warning;
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_LOW:
|
||||
level = NS_info;
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
level = NS_debug;
|
||||
break;
|
||||
|
||||
default:
|
||||
level = NS_fatal; //???
|
||||
break;
|
||||
}
|
||||
|
||||
string msg_str(message, length);
|
||||
GLCAT.out(level) << msg_str << "\n";
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (level >= gl_debug_abort_level.get_value()) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GLGraphicsStateGuardian::reset
|
||||
// Access: Public, Virtual
|
||||
@ -386,10 +429,65 @@ reset() {
|
||||
}
|
||||
|
||||
// Save the extensions tokens.
|
||||
_extensions.clear();
|
||||
save_extensions((const char *)glGetString(GL_EXTENSIONS));
|
||||
get_extra_extensions();
|
||||
report_extensions();
|
||||
|
||||
// Initialize OpenGL debugging output first, if enabled and supported.
|
||||
if (gl_debug) {
|
||||
bool supports_debug = false;
|
||||
PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
|
||||
PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
|
||||
|
||||
if (is_at_least_gl_version(4, 3) || has_extension("GL_KHR_debug")) {
|
||||
#ifdef OPENGLES
|
||||
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
|
||||
get_extension_func("glDebugMessageCallbackKHR");
|
||||
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
|
||||
get_extension_func("glDebugMessageControlKHR");
|
||||
#else
|
||||
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
|
||||
get_extension_func("glDebugMessageCallback");
|
||||
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
|
||||
get_extension_func("glDebugMessageControl");
|
||||
#endif
|
||||
glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
|
||||
supports_debug = true;
|
||||
|
||||
} else if (has_extension("GL_ARB_debug_output")) {
|
||||
_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
|
||||
get_extension_func("glDebugMessageCallbackARB");
|
||||
_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
|
||||
get_extension_func("glDebugMessageControlARB");
|
||||
supports_debug = true;
|
||||
}
|
||||
|
||||
if (supports_debug) {
|
||||
// Set the categories we want to listen to.
|
||||
_glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
|
||||
0, NULL, GLCAT.is_error());
|
||||
_glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
|
||||
0, NULL, GLCAT.is_warning());
|
||||
_glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW,
|
||||
0, NULL, GLCAT.is_info());
|
||||
_glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
|
||||
0, NULL, GLCAT.is_debug());
|
||||
|
||||
// Enable the callback.
|
||||
_glDebugMessageCallback(&debug_callback, (void*)this);
|
||||
if (gl_debug_synchronous) {
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
}
|
||||
|
||||
GLCAT.error() << "gl-debug enabled.\n";
|
||||
} else {
|
||||
GLCAT.error() << "gl-debug enabled, but NOT supported.\n";
|
||||
}
|
||||
} else {
|
||||
GLCAT.debug() << "gl-debug NOT enabled.\n";
|
||||
}
|
||||
|
||||
_supported_geom_rendering =
|
||||
Geom::GR_indexed_point |
|
||||
Geom::GR_point | Geom::GR_point_uniform_size |
|
||||
@ -634,7 +732,6 @@ reset() {
|
||||
}
|
||||
#endif
|
||||
|
||||
_cube_map_seamless = false;
|
||||
#ifdef OPENGLES_2
|
||||
_supports_cube_map = true;
|
||||
#else
|
||||
@ -644,7 +741,7 @@ reset() {
|
||||
|
||||
if (_supports_cube_map && gl_cube_map_seamless) {
|
||||
if (is_at_least_gl_version(3, 2) || has_extension("GL_ARB_seamless_cube_map")) {
|
||||
_cube_map_seamless = true;
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -2235,10 +2332,6 @@ begin_frame(Thread *current_thread) {
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
if (_cube_map_seamless) {
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
|
||||
if (_current_properties->get_srgb_color()) {
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ typedef double GLdouble;
|
||||
// functions are defined, and the system gl.h sometimes doesn't
|
||||
// declare these typedefs.
|
||||
#if !defined( __EDG__ ) || defined( __INTEL_COMPILER ) // Protect the following from the Tau instrumentor and expose it for the intel compiler.
|
||||
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
|
||||
typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
|
||||
typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
|
||||
@ -196,6 +199,8 @@ public:
|
||||
virtual int get_driver_shader_version_major();
|
||||
virtual int get_driver_shader_version_minor();
|
||||
|
||||
static void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
|
||||
|
||||
virtual void reset();
|
||||
|
||||
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
|
||||
@ -543,6 +548,7 @@ protected:
|
||||
int _gl_version_major, _gl_version_minor;
|
||||
//#--- Zhao Nov/2011
|
||||
int _gl_shadlang_ver_major, _gl_shadlang_ver_minor;
|
||||
|
||||
pset<string> _extensions;
|
||||
|
||||
public:
|
||||
@ -582,7 +588,6 @@ public:
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC _glCompressedTexSubImage3D;
|
||||
PFNGLGETCOMPRESSEDTEXIMAGEPROC _glGetCompressedTexImage;
|
||||
|
||||
bool _cube_map_seamless;
|
||||
bool _supports_bgr;
|
||||
bool _supports_rescale_normal;
|
||||
|
||||
|
@ -126,6 +126,31 @@ ConfigVariableEnum<GeomEnums::UsageHint> gl_min_buffer_usage_hint
|
||||
"of reusing the same buffers. Consider increasing "
|
||||
"released-vbuffer-cache-size instead."));
|
||||
|
||||
ConfigVariableBool gl_debug
|
||||
("gl-debug", false,
|
||||
PRC_DESC("Setting this to true will cause OpenGL to emit more useful "
|
||||
"error and debug messages, at a slight runtime performance cost. "
|
||||
"notify-level-glgsg controls which severity levels are shown."));
|
||||
|
||||
ConfigVariableBool gl_debug_synchronous
|
||||
("gl-debug-synchronous", false,
|
||||
PRC_DESC("Set this true to make sure that the errors generated by "
|
||||
"gl-debug are reported as soon as they happen. This is "
|
||||
"highly recommended if you want to attach a debugger since "
|
||||
"the call stack may otherwise not point to the GL call "
|
||||
"where the error originated."));
|
||||
|
||||
ConfigVariableEnum<NotifySeverity> gl_debug_abort_level
|
||||
("gl-debug-abort-level", NS_fatal,
|
||||
PRC_DESC("Set this to a setting other than 'fatal' to cause an "
|
||||
"abort to be triggered when an error of the indicated "
|
||||
"severity level (or a more severe one) occurs. This is "
|
||||
"useful if you want to attach a debugger. If you set this, "
|
||||
"it is highly recommended to also set gl-debug-synchronous, "
|
||||
"since the call stack will otherwise not point to the GL call "
|
||||
"that triggered the error message. "
|
||||
"This feature is not available when NDEBUG has been defined."));
|
||||
|
||||
ConfigVariableBool gl_debug_buffers
|
||||
("gl-debug-buffers", false,
|
||||
PRC_DESC("Set this true, in addition to enabling debug notify for "
|
||||
|
@ -55,6 +55,9 @@ extern ConfigVariableBool gl_interleaved_arrays;
|
||||
extern ConfigVariableBool gl_parallel_arrays;
|
||||
extern ConfigVariableInt gl_max_errors;
|
||||
extern ConfigVariableEnum<GeomEnums::UsageHint> gl_min_buffer_usage_hint;
|
||||
extern ConfigVariableBool gl_debug;
|
||||
extern ConfigVariableBool gl_debug_synchronous;
|
||||
extern ConfigVariableEnum<NotifySeverity> gl_debug_abort_level;
|
||||
extern ConfigVariableBool gl_debug_buffers;
|
||||
extern ConfigVariableBool gl_finish;
|
||||
extern ConfigVariableBool gl_force_depth_stencil;
|
||||
|
@ -2398,6 +2398,50 @@ extern "C" {
|
||||
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
|
||||
#endif
|
||||
|
||||
#ifndef GL_KHR_debug
|
||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
|
||||
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
|
||||
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
|
||||
#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
|
||||
#define GL_DEBUG_SOURCE_API 0x8246
|
||||
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
|
||||
#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
|
||||
#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
|
||||
#define GL_DEBUG_SOURCE_APPLICATION 0x824A
|
||||
#define GL_DEBUG_SOURCE_OTHER 0x824B
|
||||
#define GL_DEBUG_TYPE_ERROR 0x824C
|
||||
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
|
||||
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
|
||||
#define GL_DEBUG_TYPE_PORTABILITY 0x824F
|
||||
#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
|
||||
#define GL_DEBUG_TYPE_OTHER 0x8251
|
||||
#define GL_DEBUG_TYPE_MARKER 0x8268
|
||||
#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
|
||||
#define GL_DEBUG_TYPE_POP_GROUP 0x826A
|
||||
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
|
||||
#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
|
||||
#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
|
||||
#define GL_BUFFER 0x82E0
|
||||
#define GL_SHADER 0x82E1
|
||||
#define GL_PROGRAM 0x82E2
|
||||
#define GL_QUERY 0x82E3
|
||||
#define GL_PROGRAM_PIPELINE 0x82E4
|
||||
#define GL_SAMPLER 0x82E6
|
||||
#define GL_DISPLAY_LIST 0x82E7
|
||||
/* DISPLAY_LIST used in compatibility profile only */
|
||||
#define GL_MAX_LABEL_LENGTH 0x82E8
|
||||
#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
|
||||
#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
|
||||
#define GL_DEBUG_LOGGED_MESSAGES 0x9145
|
||||
#define GL_DEBUG_SEVERITY_HIGH 0x9146
|
||||
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
|
||||
#define GL_DEBUG_SEVERITY_LOW 0x9148
|
||||
#define GL_DEBUG_OUTPUT 0x92E0
|
||||
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
|
||||
/* reuse GL_STACK_UNDERFLOW */
|
||||
/* reuse GL_STACK_OVERFLOW */
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_compute_shader
|
||||
#define GL_COMPUTE_SHADER 0x91B9
|
||||
#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
|
||||
@ -5597,6 +5641,10 @@ typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLen
|
||||
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
|
||||
#endif
|
||||
|
||||
#ifndef GL_KHR_debug
|
||||
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
|
||||
#endif
|
||||
|
||||
#ifndef GL_NV_vdpau_interop
|
||||
typedef GLintptr GLvdpauSurfaceNV;
|
||||
#endif
|
||||
@ -7903,6 +7951,32 @@ typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum ta
|
||||
typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
|
||||
#endif
|
||||
|
||||
#ifndef GL_KHR_debug
|
||||
#define GL_KHR_debug 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
|
||||
GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
|
||||
GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
|
||||
GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
|
||||
GLAPI void APIENTRY glPopDebugGroup (void);
|
||||
GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
|
||||
GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
|
||||
GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
|
||||
GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
|
||||
#endif /* GL_GLEXT_PROTOTYPES */
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
|
||||
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
|
||||
typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
|
||||
typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
|
||||
typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
|
||||
typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
|
||||
typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
|
||||
typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
|
||||
typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_compute_shader
|
||||
#define GL_ARB_compute_shader 1
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
|
@ -295,6 +295,11 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
||||
int best_result = 0;
|
||||
FrameBufferProperties best_props;
|
||||
|
||||
int render_type = GLX_RGBA_TYPE;
|
||||
if (properties.get_indexed_color()) {
|
||||
render_type = GLX_COLOR_INDEX_TYPE;
|
||||
}
|
||||
|
||||
static const int max_attrib_list = 32;
|
||||
int attrib_list[max_attrib_list];
|
||||
int n = 0;
|
||||
@ -324,7 +329,8 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
||||
const char *pixmaptext = context_has_pixmap ? " (pixmap)" : "";
|
||||
const char *slowtext = slow ? " (slow)" : "";
|
||||
glxdisplay_cat.debug()
|
||||
<< i << ": " << fbprops << " quality=" << quality << pbuffertext << pixmaptext << slowtext << "\n";
|
||||
<< i << ": " << fbprops << " quality=" << quality << pbuffertext
|
||||
<< pixmaptext << slowtext << "\n";
|
||||
}
|
||||
if (need_pbuffer && !context_has_pbuffer) {
|
||||
continue;
|
||||
@ -343,10 +349,29 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
||||
|
||||
if (best_quality > 0) {
|
||||
_fbconfig = configs[best_result];
|
||||
_context =
|
||||
_glXCreateNewContext(_display, _fbconfig, GLX_RGBA_TYPE, _share_context,
|
||||
GL_TRUE);
|
||||
|
||||
if (_glXCreateContextAttribs != NULL) {
|
||||
// NB. This is a wholly different type of attrib list
|
||||
// than below, the same values are not used!
|
||||
n = 0;
|
||||
attrib_list[n++] = GLX_RENDER_TYPE;
|
||||
attrib_list[n++] = render_type;
|
||||
if (gl_debug) {
|
||||
attrib_list[n++] = GLX_CONTEXT_FLAGS_ARB;
|
||||
attrib_list[n++] = GLX_CONTEXT_DEBUG_BIT_ARB;
|
||||
}
|
||||
attrib_list[n] = None;
|
||||
_context = _glXCreateContextAttribs(_display, _fbconfig, _share_context,
|
||||
GL_TRUE, attrib_list);
|
||||
} else {
|
||||
_context =
|
||||
_glXCreateNewContext(_display, _fbconfig, render_type, _share_context,
|
||||
GL_TRUE);
|
||||
}
|
||||
|
||||
if (_context) {
|
||||
mark_new();
|
||||
|
||||
if (_visuals != (XVisualInfo *)NULL) {
|
||||
XFree(_visuals);
|
||||
_visuals = NULL;
|
||||
@ -398,150 +423,6 @@ choose_pixel_format(const FrameBufferProperties &properties,
|
||||
_context_has_pbuffer = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsStateGuardian::reset
|
||||
// Access: Public, Virtual
|
||||
// Description: Resets all internal state as if the gsg were newly
|
||||
// created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsStateGuardian::
|
||||
reset() {
|
||||
PosixGraphicsStateGuardian::reset();
|
||||
|
||||
_supports_swap_control = has_extension("GLX_SGI_swap_control");
|
||||
|
||||
if (_supports_swap_control) {
|
||||
_glXSwapIntervalSGI =
|
||||
(PFNGLXSWAPINTERVALSGIPROC)get_extension_func("glXSwapIntervalSGI");
|
||||
if (_glXSwapIntervalSGI == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGI_swap_control extension, but does not define all functions.\n";
|
||||
_supports_swap_control = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_supports_swap_control) {
|
||||
// Set the video-sync setting up front, if we have the extension
|
||||
// that supports it.
|
||||
_glXSwapIntervalSGI(sync_video ? 1 : 0);
|
||||
}
|
||||
|
||||
if (glx_support_fbconfig) {
|
||||
if (glx_is_at_least_version(1, 3)) {
|
||||
// If we have glx 1.3 or better, we have the FBConfig interface.
|
||||
_supports_fbconfig = true;
|
||||
|
||||
_glXChooseFBConfig =
|
||||
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfig");
|
||||
_glXCreateNewContext =
|
||||
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateNewContext");
|
||||
_glXGetVisualFromFBConfig =
|
||||
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfig");
|
||||
_glXGetFBConfigAttrib =
|
||||
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttrib");
|
||||
_glXCreatePixmap =
|
||||
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreatePixmap");
|
||||
|
||||
if (_glXChooseFBConfig == NULL ||
|
||||
_glXCreateNewContext == NULL ||
|
||||
_glXGetVisualFromFBConfig == NULL ||
|
||||
_glXGetFBConfigAttrib == NULL ||
|
||||
_glXCreatePixmap == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
|
||||
_supports_fbconfig = false;
|
||||
}
|
||||
} else if (has_extension("GLX_SGIX_fbconfig")) {
|
||||
// Or maybe we have the old SGIX extension for FBConfig. This is
|
||||
// the same, but the function names are different--we just remap
|
||||
// them to the same function pointers.
|
||||
_supports_fbconfig = true;
|
||||
|
||||
_glXChooseFBConfig =
|
||||
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfigSGIX");
|
||||
_glXCreateNewContext =
|
||||
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateContextWithConfigSGIX");
|
||||
_glXGetVisualFromFBConfig =
|
||||
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfigSGIX");
|
||||
_glXGetFBConfigAttrib =
|
||||
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttribSGIX");
|
||||
_glXCreatePixmap =
|
||||
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreateGLXPixmapWithConfigSGIX");
|
||||
|
||||
if (_glXChooseFBConfig == NULL ||
|
||||
_glXCreateNewContext == NULL ||
|
||||
_glXGetVisualFromFBConfig == NULL ||
|
||||
_glXGetFBConfigAttrib == NULL ||
|
||||
_glXCreatePixmap == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
|
||||
_supports_fbconfig = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (glx_is_at_least_version(1, 3)) {
|
||||
// If we have glx 1.3 or better, we have the PBuffer interface.
|
||||
_supports_pbuffer = true;
|
||||
_uses_sgix_pbuffer = false;
|
||||
|
||||
_glXCreatePbuffer =
|
||||
(PFNGLXCREATEPBUFFERPROC)get_extension_func("glXCreatePbuffer");
|
||||
_glXCreateGLXPbufferSGIX = NULL;
|
||||
_glXDestroyPbuffer =
|
||||
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyPbuffer");
|
||||
if (_glXCreatePbuffer == NULL ||
|
||||
_glXDestroyPbuffer == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
|
||||
_supports_pbuffer = false;
|
||||
}
|
||||
|
||||
} else if (has_extension("GLX_SGIX_pbuffer")) {
|
||||
// Or maybe we have the old SGIX extension for PBuffers.
|
||||
_uses_sgix_pbuffer = true;
|
||||
|
||||
// CreatePbuffer has a different form between SGIX and 1.3,
|
||||
// however, so we must treat it specially. But we can use the
|
||||
// same function pointer for DestroyPbuffer.
|
||||
_glXCreatePbuffer = NULL;
|
||||
_glXCreateGLXPbufferSGIX =
|
||||
(PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glXCreateGLXPbufferSGIX");
|
||||
_glXDestroyPbuffer =
|
||||
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyGLXPbufferSGIX");
|
||||
if (_glXCreateGLXPbufferSGIX == NULL ||
|
||||
_glXDestroyPbuffer == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
|
||||
_supports_pbuffer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (glxdisplay_cat.is_debug()) {
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_swap_control = " << _supports_swap_control << "\n";
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_fbconfig = " << _supports_fbconfig << "\n";
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_pbuffer = " << _supports_pbuffer
|
||||
<< " sgix = " << _uses_sgix_pbuffer << "\n";
|
||||
}
|
||||
|
||||
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
|
||||
// found, it's actually a Mesa-based OpenGL layer running over a
|
||||
// hardware driver.
|
||||
if (_gl_renderer.find("Mesa") != string::npos &&
|
||||
_gl_renderer.find("Mesa DRI") == string::npos) {
|
||||
// It's Mesa, therefore probably a software context.
|
||||
_fbprops.set_force_software(1);
|
||||
_fbprops.set_force_hardware(0);
|
||||
} else {
|
||||
_fbprops.set_force_hardware(1);
|
||||
_fbprops.set_force_software(0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsStateGuardian::glx_is_at_least_version
|
||||
// Access: Public
|
||||
@ -692,6 +573,153 @@ do_get_extension_func(const char *name) {
|
||||
return PosixGraphicsStateGuardian::do_get_extension_func(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsStateGuardian::query_glx_extensions
|
||||
// Access: Private
|
||||
// Description: Queries the GLX extension pointers.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void glxGraphicsStateGuardian::
|
||||
query_glx_extensions() {
|
||||
_supports_swap_control = has_extension("GLX_SGI_swap_control");
|
||||
|
||||
if (_supports_swap_control) {
|
||||
_glXSwapIntervalSGI =
|
||||
(PFNGLXSWAPINTERVALSGIPROC)get_extension_func("glXSwapIntervalSGI");
|
||||
if (_glXSwapIntervalSGI == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGI_swap_control extension, but does not define all functions.\n";
|
||||
_supports_swap_control = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_supports_swap_control) {
|
||||
// Set the video-sync setting up front, if we have the extension
|
||||
// that supports it.
|
||||
_glXSwapIntervalSGI(sync_video ? 1 : 0);
|
||||
}
|
||||
|
||||
if (glx_support_fbconfig) {
|
||||
if (glx_is_at_least_version(1, 3)) {
|
||||
// If we have glx 1.3 or better, we have the FBConfig interface.
|
||||
_supports_fbconfig = true;
|
||||
|
||||
_glXChooseFBConfig =
|
||||
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfig");
|
||||
_glXCreateNewContext =
|
||||
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateNewContext");
|
||||
_glXGetVisualFromFBConfig =
|
||||
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfig");
|
||||
_glXGetFBConfigAttrib =
|
||||
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttrib");
|
||||
_glXCreatePixmap =
|
||||
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreatePixmap");
|
||||
|
||||
if (_glXChooseFBConfig == NULL ||
|
||||
_glXCreateNewContext == NULL ||
|
||||
_glXGetVisualFromFBConfig == NULL ||
|
||||
_glXGetFBConfigAttrib == NULL ||
|
||||
_glXCreatePixmap == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
|
||||
_supports_fbconfig = false;
|
||||
}
|
||||
} else if (has_extension("GLX_SGIX_fbconfig")) {
|
||||
// Or maybe we have the old SGIX extension for FBConfig. This is
|
||||
// the same, but the function names are different--we just remap
|
||||
// them to the same function pointers.
|
||||
_supports_fbconfig = true;
|
||||
|
||||
_glXChooseFBConfig =
|
||||
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfigSGIX");
|
||||
_glXCreateNewContext =
|
||||
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateContextWithConfigSGIX");
|
||||
_glXGetVisualFromFBConfig =
|
||||
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfigSGIX");
|
||||
_glXGetFBConfigAttrib =
|
||||
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttribSGIX");
|
||||
_glXCreatePixmap =
|
||||
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreateGLXPixmapWithConfigSGIX");
|
||||
|
||||
if (_glXChooseFBConfig == NULL ||
|
||||
_glXCreateNewContext == NULL ||
|
||||
_glXGetVisualFromFBConfig == NULL ||
|
||||
_glXGetFBConfigAttrib == NULL ||
|
||||
_glXCreatePixmap == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
|
||||
_supports_fbconfig = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (glx_is_at_least_version(1, 3)) {
|
||||
// If we have glx 1.3 or better, we have the PBuffer interface.
|
||||
_supports_pbuffer = true;
|
||||
_uses_sgix_pbuffer = false;
|
||||
|
||||
_glXCreatePbuffer =
|
||||
(PFNGLXCREATEPBUFFERPROC)get_extension_func("glXCreatePbuffer");
|
||||
_glXCreateGLXPbufferSGIX = NULL;
|
||||
_glXDestroyPbuffer =
|
||||
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyPbuffer");
|
||||
if (_glXCreatePbuffer == NULL ||
|
||||
_glXDestroyPbuffer == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
|
||||
_supports_pbuffer = false;
|
||||
}
|
||||
|
||||
} else if (has_extension("GLX_SGIX_pbuffer")) {
|
||||
// Or maybe we have the old SGIX extension for PBuffers.
|
||||
_uses_sgix_pbuffer = true;
|
||||
|
||||
// CreatePbuffer has a different form between SGIX and 1.3,
|
||||
// however, so we must treat it specially. But we can use the
|
||||
// same function pointer for DestroyPbuffer.
|
||||
_glXCreatePbuffer = NULL;
|
||||
_glXCreateGLXPbufferSGIX =
|
||||
(PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glXCreateGLXPbufferSGIX");
|
||||
_glXDestroyPbuffer =
|
||||
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyGLXPbufferSGIX");
|
||||
if (_glXCreateGLXPbufferSGIX == NULL ||
|
||||
_glXDestroyPbuffer == NULL) {
|
||||
glxdisplay_cat.error()
|
||||
<< "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
|
||||
_supports_pbuffer = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_extension("GLX_ARB_create_context")) {
|
||||
_glXCreateContextAttribs =
|
||||
(PFNGLXCREATECONTEXTATTRIBSARBPROC)get_extension_func("glXCreateContextAttribsARB");
|
||||
} else {
|
||||
_glXCreateContextAttribs = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (glxdisplay_cat.is_debug()) {
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_swap_control = " << _supports_swap_control << "\n";
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_fbconfig = " << _supports_fbconfig << "\n";
|
||||
glxdisplay_cat.debug()
|
||||
<< "supports_pbuffer = " << _supports_pbuffer
|
||||
<< " sgix = " << _uses_sgix_pbuffer << "\n";
|
||||
}
|
||||
|
||||
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
|
||||
// found, it's actually a Mesa-based OpenGL layer running over a
|
||||
// hardware driver.
|
||||
if (_gl_renderer.find("Mesa") != string::npos &&
|
||||
_gl_renderer.find("Mesa DRI") == string::npos) {
|
||||
// It's Mesa, therefore probably a software context.
|
||||
_fbprops.set_force_software(1);
|
||||
_fbprops.set_force_hardware(0);
|
||||
} else {
|
||||
_fbprops.set_force_hardware(1);
|
||||
_fbprops.set_force_software(0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: glxGraphicsStateGuardian::show_glx_client_string
|
||||
// Access: Protected
|
||||
@ -814,8 +842,11 @@ init_temp_context() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now use it to query the available GLX features.
|
||||
glXMakeCurrent(_display, _temp_xwindow, _temp_context);
|
||||
reset();
|
||||
query_gl_version();
|
||||
get_extra_extensions();
|
||||
query_glx_extensions();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -67,7 +67,7 @@ typedef int (* PFNGLXGETFBCONFIGATTRIBPROC) (X11_Display *dpy, GLXFBConfig confi
|
||||
typedef GLXPixmap (* PFNGLXCREATEPIXMAPPROC) (X11_Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
|
||||
typedef GLXPbuffer (* PFNGLXCREATEPBUFFERPROC) (X11_Display *dpy, GLXFBConfig config, const int *attrib_list);
|
||||
typedef void (* PFNGLXDESTROYPBUFFERPROC) (X11_Display *dpy, GLXPbuffer pbuf);
|
||||
|
||||
typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (X11_Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
|
||||
#endif // __EDG__
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -92,8 +92,6 @@ public:
|
||||
|
||||
virtual ~glxGraphicsStateGuardian();
|
||||
|
||||
virtual void reset();
|
||||
|
||||
bool glx_is_at_least_version(int major_version, int minor_version) const;
|
||||
|
||||
GLXContext _share_context;
|
||||
@ -119,6 +117,7 @@ public:
|
||||
PFNGLXGETVISUALFROMFBCONFIGPROC _glXGetVisualFromFBConfig;
|
||||
PFNGLXGETFBCONFIGATTRIBPROC _glXGetFBConfigAttrib;
|
||||
PFNGLXCREATEPIXMAPPROC _glXCreatePixmap;
|
||||
PFNGLXCREATECONTEXTATTRIBSARBPROC _glXCreateContextAttribs;
|
||||
|
||||
bool _supports_pbuffer; // true if the interface is available.
|
||||
bool _uses_sgix_pbuffer;
|
||||
@ -135,6 +134,7 @@ protected:
|
||||
virtual void *do_get_extension_func(const char *name);
|
||||
|
||||
private:
|
||||
void query_glx_extensions();
|
||||
void show_glx_client_string(const string &name, int id);
|
||||
void show_glx_server_string(const string &name, int id);
|
||||
void choose_temp_visual(const FrameBufferProperties &properties);
|
||||
|
Loading…
x
Reference in New Issue
Block a user