Support specifying custom gl-version or requesting debug context on Windows

Also works around NVIDIA driver bug where GL_VERSION is always reported as 1.2 for pview.exe
This commit is contained in:
rdb 2015-07-18 22:40:57 +02:00
parent 96a9e22395
commit e91a9100ed
4 changed files with 103 additions and 15 deletions

View File

@ -6835,10 +6835,9 @@ show_gl_string(const string &name, GLenum id) {
const GLubyte *text = glGetString(id); const GLubyte *text = glGetString(id);
if (text == (const GLubyte *)NULL) { if (text == (const GLubyte *)NULL) {
if (GLCAT.is_debug()) { GLCAT.warning()
GLCAT.debug() << "Unable to query " << name << "\n";
<< "Unable to query " << name << "\n";
}
} else { } else {
result = (const char *)text; result = (const char *)text;
if (GLCAT.is_debug()) { if (GLCAT.is_debug()) {
@ -6859,20 +6858,60 @@ void CLP(GraphicsStateGuardian)::
query_gl_version() { query_gl_version() {
_gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR); _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
_gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER); _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
_gl_version = show_gl_string("GL_VERSION", GL_VERSION);
_gl_version_major = 0; _gl_version_major = 0;
_gl_version_minor = 0; _gl_version_minor = 0;
// This is the most preposterous driver bug: NVIDIA drivers will claim
// that the version is 1.2 as long as the process is named pview.exe!
#ifndef OPENGLES
if (_gl_version.substr(0, 10) == "1.2 NVIDIA") {
Filename exec_name = ExecutionEnvironment::get_binary_name();
if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) {
glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
if (glGetError() == GL_INVALID_ENUM) {
_gl_version_major = 1;
_gl_version_minor = 2;
GLCAT.warning()
<< "Driver possibly misreported GL_VERSION! Unable to detect "
"correct OpenGL version.\n";
} else if (_gl_version_major != 1 || _gl_version_minor != 2) {
GLCAT.debug()
<< "Driver misreported GL_VERSION! Correct version detected as "
<< _gl_version_major << "." << _gl_version_minor << "\n";
}
return;
}
}
#endif
// If we asked for a GL 3 context, let's first try and see if we
// can use the OpenGL 3 way to query version.
if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) {
glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
if (_gl_version_major >= 1) {
// Fair enough, seems to check out.
if (GLCAT.is_debug()) {
GLCAT.debug()
<< "Detected OpenGL version: "
<< _gl_version_major << "." << _gl_version_minor << "\n";
}
return;
}
}
// Otherwise, parse the GL_VERSION string.
if (_gl_version.empty()) {
GLCAT.error() << "Unable to detect OpenGL version\n";
const GLubyte *text = glGetString(GL_VERSION);
if (text == (const GLubyte *)NULL) {
GLCAT.warning()
<< "Unable to query GL_VERSION\n";
} else { } else {
string version((const char *)text); string input = _gl_version;
_gl_version = version;
string input = version;
// Skip any initial words that don't begin with a digit. // Skip any initial words that don't begin with a digit.
while (!input.empty() && !isdigit(input[0])) { while (!input.empty() && !isdigit(input[0])) {
@ -6904,7 +6943,7 @@ query_gl_version() {
if (GLCAT.is_debug()) { if (GLCAT.is_debug()) {
GLCAT.debug() GLCAT.debug()
<< "GL_VERSION = " << version << ", decoded to " << "GL_VERSION decoded to: "
<< _gl_version_major << "." << _gl_version_minor << _gl_version_major << "." << _gl_version_minor
<< "\n"; << "\n";
} }

View File

@ -47,6 +47,8 @@ wglGraphicsStateGuardian(GraphicsEngine *engine, GraphicsPipe *pipe,
_supports_wgl_multisample = false; _supports_wgl_multisample = false;
_supports_wgl_render_texture = false; _supports_wgl_render_texture = false;
_wglCreateContextAttribsARB = NULL;
get_gamma_table(); get_gamma_table();
atexit(atexit_function); atexit(atexit_function);
} }
@ -345,6 +347,14 @@ choose_pixel_format(const FrameBufferProperties &properties,
get_extra_extensions(); get_extra_extensions();
_supports_pixel_format = has_extension("WGL_ARB_pixel_format"); _supports_pixel_format = has_extension("WGL_ARB_pixel_format");
_supports_wgl_multisample = has_extension("WGL_ARB_multisample"); _supports_wgl_multisample = has_extension("WGL_ARB_multisample");
if (has_extension("WGL_ARB_create_context")) {
_wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
} else {
_wglCreateContextAttribsARB = NULL;
}
_extensions.clear(); _extensions.clear();
if (!_supports_pixel_format) { if (!_supports_pixel_format) {
@ -614,7 +624,34 @@ make_context(HDC hdc) {
// Attempt to create a context. // Attempt to create a context.
wglGraphicsPipe::_current_valid = false; wglGraphicsPipe::_current_valid = false;
_context = wglCreateContext(hdc);
if (_wglCreateContextAttribsARB != NULL) {
// We have a fancier version of wglCreateContext that allows us
// to specify what kind of OpenGL context we would like.
int attrib_list[32];
int n = 0;
attrib_list[0] = NULL;
if (gl_version.get_num_words() > 0) {
attrib_list[n++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
attrib_list[n++] = gl_version[0];
if (gl_version.get_num_words() > 1) {
attrib_list[n++] = WGL_CONTEXT_MINOR_VERSION_ARB;
attrib_list[n++] = gl_version[1];
}
}
if (gl_debug) {
attrib_list[n++] = WGL_CONTEXT_FLAGS_ARB;
attrib_list[n++] = WGL_CONTEXT_DEBUG_BIT_ARB;
}
attrib_list[n++] = WGL_CONTEXT_PROFILE_MASK_ARB;
attrib_list[n++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
attrib_list[n] = NULL;
_context = _wglCreateContextAttribsARB(hdc, 0, attrib_list);
} else {
_context = wglCreateContext(hdc);
}
if (_context == NULL) { if (_context == NULL) {
wgldisplay_cat.error() wgldisplay_cat.error()

View File

@ -118,6 +118,8 @@ public:
PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB; PFNWGLRELEASETEXIMAGEARBPROC _wglReleaseTexImageARB;
PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB; PFNWGLSETPBUFFERATTRIBARBPROC _wglSetPbufferAttribARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC _wglCreateContextAttribsARB;
public: public:
static TypeHandle get_class_type() { static TypeHandle get_class_type() {
return _type_handle; return _type_handle;

View File

@ -304,8 +304,18 @@ open_window() {
// Initializes _colormap // Initializes _colormap
setup_colormap(pixelformat); setup_colormap(pixelformat);
// Make sure we have a context created.
HGLRC context = wglgsg->get_context(_hdc);
if (!context) {
// The context failed to create for some reason.
wgldisplay_cat.error()
<< "Closing window because no valid context is available.\n";
close_window();
return false;
}
// Initialize the gsg. // Initialize the gsg.
wglGraphicsPipe::wgl_make_current(_hdc, wglgsg->get_context(_hdc), &_make_current_pcollector); wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector);
wglgsg->reset_if_new(); wglgsg->reset_if_new();
wglgsg->report_my_gl_errors(); wglgsg->report_my_gl_errors();
if (!wglgsg->get_fb_properties().verify_hardware_software if (!wglgsg->get_fb_properties().verify_hardware_software