Browse Source

more reliably check for Mesa

David Rose 20 years ago
parent
commit
d439425648

+ 14 - 1
panda/src/display/graphicsStateGuardian.I

@@ -116,7 +116,7 @@ set_active(bool active) {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE bool GraphicsStateGuardian::
 INLINE bool GraphicsStateGuardian::
 is_active() const {
 is_active() const {
-  return _active;
+  return _active && _is_valid;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -539,6 +539,19 @@ mark_new() {
   _needs_reset = true;
   _needs_reset = true;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::is_valid
+//       Access: Public
+//  Description: Returns true if the GSG has been correctly
+//               initialized within a graphics context, false if there
+//               has been some problem or it hasn't been initialized
+//               yet.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+is_valid() const {
+  return _is_valid;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::modify_state
 //     Function: GraphicsStateGuardian::modify_state
 //       Access: Public
 //       Access: Public

+ 4 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -105,6 +105,7 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
   _current_display_region = (DisplayRegion*)0L;
   _current_display_region = (DisplayRegion*)0L;
   _current_lens = (Lens *)NULL;
   _current_lens = (Lens *)NULL;
   _needs_reset = true;
   _needs_reset = true;
+  _is_valid = false;
   _closing_gsg = false;
   _closing_gsg = false;
   _active = true;
   _active = true;
   _prepared_objects = new PreparedGraphicsObjects;
   _prepared_objects = new PreparedGraphicsObjects;
@@ -207,6 +208,7 @@ get_supported_geom_rendering() const {
 void GraphicsStateGuardian::
 void GraphicsStateGuardian::
 reset() {
 reset() {
   _needs_reset = false;
   _needs_reset = false;
+  _is_valid = false;
 
 
   _display_region_stack_level = 0;
   _display_region_stack_level = 0;
   _frame_buffer_stack_level = 0;
   _frame_buffer_stack_level = 0;
@@ -261,6 +263,8 @@ reset() {
   _needs_tex_gen = false;
   _needs_tex_gen = false;
   _tex_gen_modifies_mat = false;
   _tex_gen_modifies_mat = false;
   _last_max_stage_index = 0;
   _last_max_stage_index = 0;
+
+  _is_valid = true;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 2 - 0
panda/src/display/graphicsStateGuardian.h

@@ -190,6 +190,7 @@ public:
   INLINE bool reset_if_new();
   INLINE bool reset_if_new();
   INLINE void mark_new();
   INLINE void mark_new();
   virtual void reset();
   virtual void reset();
+  INLINE bool is_valid() const;
 
 
   INLINE void modify_state(const RenderState *state);
   INLINE void modify_state(const RenderState *state);
   INLINE void set_state(const RenderState *state);
   INLINE void set_state(const RenderState *state);
@@ -362,6 +363,7 @@ protected:
   int _last_max_stage_index;
   int _last_max_stage_index;
 
 
   bool _needs_reset;
   bool _needs_reset;
+  bool _is_valid;
   bool _closing_gsg;
   bool _closing_gsg;
   bool _active;
   bool _active;
 
 

+ 53 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.I

@@ -82,6 +82,59 @@ report_my_errors(int line, const char *source_file) {
 #endif
 #endif
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::get_gl_vendor
+//       Access: Public
+//  Description: Returns the GL vendor string reported by the driver.
+////////////////////////////////////////////////////////////////////
+INLINE const string &CLP(GraphicsStateGuardian)::
+get_gl_vendor() const {
+  return _gl_vendor;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::get_gl_renderer
+//       Access: Public
+//  Description: Returns the GL renderer string reported by the driver.
+////////////////////////////////////////////////////////////////////
+INLINE const string &CLP(GraphicsStateGuardian)::
+get_gl_renderer() const {
+  return _gl_renderer;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::get_gl_version_major
+//       Access: Public
+//  Description: Returns the major part of the reported GL version
+//               number.
+////////////////////////////////////////////////////////////////////
+INLINE int CLP(GraphicsStateGuardian)::
+get_gl_version_major() const {
+  return _gl_version_major;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::get_gl_version_minor
+//       Access: Public
+//  Description: Returns the minor part of the reported GL version
+//               number.
+////////////////////////////////////////////////////////////////////
+INLINE int CLP(GraphicsStateGuardian)::
+get_gl_version_minor() const {
+  return _gl_version_minor;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CLP(GraphicsStateGuardian)::get_gl_version_release
+//       Access: Public
+//  Description: Returns the release part of the reported GL version
+//               number.
+////////////////////////////////////////////////////////////////////
+INLINE int CLP(GraphicsStateGuardian)::
+get_gl_version_release() const {
+  return _gl_version_release;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CLP(GraphicsStateGuardian)::enable_multisample_antialias
 //     Function: CLP(GraphicsStateGuardian)::enable_multisample_antialias
 //       Access: Protected
 //       Access: Protected

+ 23 - 14
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -304,7 +304,7 @@ reset() {
   GraphicsStateGuardian::reset();
   GraphicsStateGuardian::reset();
 
 
   // Output the vendor and version strings.
   // Output the vendor and version strings.
-  get_gl_version();
+  query_gl_version();
 
 
   // Save the extensions tokens.
   // Save the extensions tokens.
   save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));
   save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));
@@ -2932,31 +2932,37 @@ report_errors_loop(int line, const char *source_file, GLenum error_code,
 //     Function: GLGraphicsStateGuardian::show_gl_string
 //     Function: GLGraphicsStateGuardian::show_gl_string
 //       Access: Protected
 //       Access: Protected
 //  Description: Outputs the result of glGetString() on the indicated
 //  Description: Outputs the result of glGetString() on the indicated
-//               tag.
+//               tag.  The output string is returned.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-void CLP(GraphicsStateGuardian)::
+string CLP(GraphicsStateGuardian)::
 show_gl_string(const string &name, GLenum id) {
 show_gl_string(const string &name, GLenum id) {
-  if (GLCAT.is_debug()) {
-    const GLubyte *text = GLP(GetString)(id);
-    if (text == (const GLubyte *)NULL) {
-      GLCAT.debug()
-        << "Unable to query " << name << "\n";
-    } else {
+  string result;
+
+  const GLubyte *text = GLP(GetString)(id);
+
+  if (text == (const GLubyte *)NULL) {
+    GLCAT.warning()
+      << "Unable to query " << name << "\n";
+  } else {
+    result = (const char *)text;
+    if (GLCAT.is_debug()) {
       GLCAT.debug()
       GLCAT.debug()
-        << name << " = " << (const char *)text << "\n";
+        << name << " = " << result << "\n";
     }
     }
   }
   }
+
+  return result;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: GLGraphicsStateGuardian::get_gl_version
+//     Function: GLGraphicsStateGuardian::query_gl_version
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
 //  Description: Queries the runtime version of OpenGL in use.
 //  Description: Queries the runtime version of OpenGL in use.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
-get_gl_version() {
-  show_gl_string("GL_VENDOR", GL_VENDOR);
-  show_gl_string("GL_RENDERER", GL_RENDERER);
+query_gl_version() {
+  _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
+  _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
 
 
   _gl_version_major = 0;
   _gl_version_major = 0;
   _gl_version_minor = 0;
   _gl_version_minor = 0;
@@ -4360,6 +4366,9 @@ finish_modify_state() {
         GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
         GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
         got_point_sprites = true;
         got_point_sprites = true;
         break;
         break;
+
+      case TexGenAttrib::M_unused:
+        break;
       }
       }
     }
     }
 
 

+ 10 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -158,11 +158,17 @@ public:
   INLINE static bool report_errors(int line, const char *source_file);
   INLINE static bool report_errors(int line, const char *source_file);
   INLINE void report_my_errors(int line, const char *source_file);
   INLINE void report_my_errors(int line, const char *source_file);
 
 
+  INLINE const string &get_gl_vendor() const;
+  INLINE const string &get_gl_renderer() const;
+  INLINE int get_gl_version_major() const;
+  INLINE int get_gl_version_minor() const;
+  INLINE int get_gl_version_release() const;
+
 protected:
 protected:
   static bool report_errors_loop(int line, const char *source_file, 
   static bool report_errors_loop(int line, const char *source_file, 
                                  GLenum error_code, int &error_count);
                                  GLenum error_code, int &error_count);
-  void show_gl_string(const string &name, GLenum id);
-  virtual void get_gl_version();
+  string show_gl_string(const string &name, GLenum id);
+  virtual void query_gl_version();
   void save_extensions(const char *extensions);
   void save_extensions(const char *extensions);
   virtual void get_extra_extensions();
   virtual void get_extra_extensions();
   void report_extensions() const;
   void report_extensions() const;
@@ -310,6 +316,8 @@ protected:
   
   
   int _error_count;
   int _error_count;
 
 
+  string _gl_vendor;
+  string _gl_renderer;
   int _gl_version_major, _gl_version_minor, _gl_version_release;
   int _gl_version_major, _gl_version_minor, _gl_version_release;
   pset<string> _extensions;
   pset<string> _extensions;
 
 

+ 18 - 43
panda/src/glxdisplay/glxGraphicsPipe.cxx

@@ -191,51 +191,26 @@ make_gsg(const FrameBufferProperties &properties,
     share_context = share_gsg->_context;
     share_context = share_gsg->_context;
   }
   }
 
 
-  int frame_buffer_mode = properties.get_frame_buffer_mode();
-  bool hardware = ((frame_buffer_mode & FrameBufferProperties::FM_hardware) != 0);
-  bool software = ((frame_buffer_mode & FrameBufferProperties::FM_software) != 0);
-  // If the user specified neither hardware nor software frame buffer,
-  // he gets either one.
-  if (!hardware && !software) {
-    hardware = true;
-    software = true;
-  }
-
   // There's no interface in GLX to query whether we have a software
   // There's no interface in GLX to query whether we have a software
   // or a hardware rendering context.  Fortunately, there seems to be
   // or a hardware rendering context.  Fortunately, there seems to be
   // only one likely software GLX context, and that's Mesa; we will
   // only one likely software GLX context, and that's Mesa; we will
   // assume that any Mesa GLX context is software-based, and any other
   // assume that any Mesa GLX context is software-based, and any other
   // context is hardware-based.
   // context is hardware-based.
 
 
-  // To determine whether we are using Mesa, we should strictly create
-  // a GL context, bind it to a window, and then examine the
-  // GL_RENDERER string, but as a cheesy shortcut to all of that hard
-  // work, we'll just check the X server's GLX_VERSION string to see
-  // if it contains "Mesa".
-
-  const char *glx_version = glXQueryServerString(_display, _screen, GLX_VERSION);
-  if (glx_version != NULL) {
-    if (strstr(glx_version, "Mesa") != NULL) {
-      // It's Mesa, therefore probably a software context.
-      if (!software) {
-        glxdisplay_cat.error()
-          << "Using GLX version " << glx_version << "; it is probably a software renderer.\n";
-        glxdisplay_cat.error()
-          << "To allow use of this display add FM_software to your frame buffer mode.\n";
-        return NULL;
-      }
-    } else {
-      // It's some other server, therefore probably a hardware context.
-      if (!hardware) {
-        glxdisplay_cat.error()
-          << "Using GLX version " << glx_version << "; it is probably hardware-accelerated.\n";
-        glxdisplay_cat.error()
-          << "To allow use of this display add FM_hardware to your frame buffer mode.\n";
-        return NULL;
-      }
-    }
-  }
-        
+  // Unforunately, to determine whether we are using Mesa, we need to
+  // create a GL context, bind it to a window, and then examine the
+  // GL_RENDERER string to see if it contains "Mesa".  So we must
+  // create the GSG and its window first, and wait until the GSG has
+  // been reset, before we can ask this question.  Therefore we don't
+  // deal with hardware/software at this point, but rather in
+  // glxGraphicsStateGuardian::reset().
+
+  // We do, however, need to determine ahead of time whether the user
+  // would prefer a hardware or software context.
+  int frame_buffer_mode = properties.get_frame_buffer_mode();
+  int want_hardware = (frame_buffer_mode & (FrameBufferProperties::FM_hardware | 
+                                            FrameBufferProperties::FM_software));
+
   FrameBufferProperties new_properties = properties;
   FrameBufferProperties new_properties = properties;
   GLXContext context = NULL;
   GLXContext context = NULL;
   XVisualInfo *visual = NULL;
   XVisualInfo *visual = NULL;
@@ -278,13 +253,13 @@ make_gsg(const FrameBufferProperties &properties,
 
 
   // Now we can make a GSG.
   // Now we can make a GSG.
   PT(glxGraphicsStateGuardian) gsg = 
   PT(glxGraphicsStateGuardian) gsg = 
-    new glxGraphicsStateGuardian(new_properties, share_gsg, context, 
-                                 visual, _display, _screen, fbconfig);
+    new glxGraphicsStateGuardian(new_properties, share_gsg, want_hardware,
+                                 context, visual, _display, _screen, fbconfig);
 
 
 #else
 #else
   PT(glxGraphicsStateGuardian) gsg = 
   PT(glxGraphicsStateGuardian) gsg = 
-    new glxGraphicsStateGuardian(new_properties, share_gsg, context, 
-                                 visual, _display, _screen);
+    new glxGraphicsStateGuardian(new_properties, share_gsg, want_hardware,
+                                 context, visual, _display, _screen);
 #endif  // HAVE_GLXFBCONFIG
 #endif  // HAVE_GLXFBCONFIG
 
 
   return gsg.p();
   return gsg.p();

+ 50 - 3
panda/src/glxdisplay/glxGraphicsStateGuardian.cxx

@@ -33,6 +33,7 @@ TypeHandle glxGraphicsStateGuardian::_type_handle;
 glxGraphicsStateGuardian::
 glxGraphicsStateGuardian::
 glxGraphicsStateGuardian(const FrameBufferProperties &properties,
 glxGraphicsStateGuardian(const FrameBufferProperties &properties,
                          glxGraphicsStateGuardian *share_with,
                          glxGraphicsStateGuardian *share_with,
+                         int want_hardware,
                          GLXContext context, XVisualInfo *visual, 
                          GLXContext context, XVisualInfo *visual, 
                          Display *display, int screen
                          Display *display, int screen
 #ifdef HAVE_GLXFBCONFIG
 #ifdef HAVE_GLXFBCONFIG
@@ -40,6 +41,7 @@ glxGraphicsStateGuardian(const FrameBufferProperties &properties,
 #endif  // HAVE_GLXFBCONFIG
 #endif  // HAVE_GLXFBCONFIG
                          ) :
                          ) :
   GLGraphicsStateGuardian(properties),
   GLGraphicsStateGuardian(properties),
+  _want_hardware(want_hardware),
   _context(context),
   _context(context),
   _visual(visual),
   _visual(visual),
   _display(display),
   _display(display),
@@ -102,6 +104,51 @@ reset() {
     // that supports it.
     // that supports it.
     _glXSwapIntervalSGI(sync_video ? 1 : 0);
     _glXSwapIntervalSGI(sync_video ? 1 : 0);
   }
   }
+
+  // Finally, check that the context is the right kind of context:
+  // hardware or software.  This really means examining the
+  // _gl_renderer string for "Mesa" (see the comment in
+  // glxGraphicsPipe).
+
+  bool hardware = ((_want_hardware & FrameBufferProperties::FM_hardware) != 0);
+  bool software = ((_want_hardware & FrameBufferProperties::FM_software) != 0);
+  // If the user specified neither hardware nor software frame buffer,
+  // he gets either one.
+  if (!hardware && !software) {
+    hardware = true;
+    software = true;
+  }
+
+  FrameBufferProperties properties = get_properties();
+  int frame_buffer_mode = properties.get_frame_buffer_mode();
+
+  if (_gl_renderer.find("Mesa") != string::npos) {
+    // It's Mesa, therefore probably a software context.
+    if (!software) {
+      glxdisplay_cat.error()
+        << "Using GL renderer " << _gl_renderer << "; it is probably a software renderer.\n";
+      glxdisplay_cat.error()
+        << "To allow use of this display add FM_software to your frame buffer mode.\n";
+      _is_valid = false;
+    }
+    frame_buffer_mode = (frame_buffer_mode | FrameBufferProperties::FM_software) & ~FrameBufferProperties::FM_hardware;
+
+  } else {
+    // It's some other renderer, therefore probably a hardware context.
+    if (!hardware) {
+      glxdisplay_cat.error()
+        << "Using GL renderer " << _gl_renderer << "; it is probably hardware-accelerated.\n";
+      glxdisplay_cat.error()
+        << "To allow use of this display add FM_hardware to your frame buffer mode.\n";
+      _is_valid = false;
+    }
+    frame_buffer_mode = (frame_buffer_mode | FrameBufferProperties::FM_hardware) & ~FrameBufferProperties::FM_software;
+  }
+
+  // Update the GSG's record to indicate whether we believe it is a
+  // hardware or software renderer.
+  properties.set_frame_buffer_mode(frame_buffer_mode);
+  set_properties(properties);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -122,13 +169,13 @@ glx_is_at_least_version(int major_version, int minor_version) const {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: glxGraphicsStateGuardian::get_gl_version
+//     Function: glxGraphicsStateGuardian::query_gl_version
 //       Access: Protected, Virtual
 //       Access: Protected, Virtual
 //  Description: Queries the runtime version of OpenGL in use.
 //  Description: Queries the runtime version of OpenGL in use.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void glxGraphicsStateGuardian::
 void glxGraphicsStateGuardian::
-get_gl_version() {
-  GLGraphicsStateGuardian::get_gl_version();
+query_gl_version() {
+  GLGraphicsStateGuardian::query_gl_version();
 
 
   show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
   show_glx_client_string("GLX_VENDOR", GLX_VENDOR);
   show_glx_client_string("GLX_VERSION", GLX_VERSION);
   show_glx_client_string("GLX_VERSION", GLX_VERSION);

+ 7 - 9
panda/src/glxdisplay/glxGraphicsStateGuardian.h

@@ -56,18 +56,15 @@ typedef int (* PFNGLXSWAPINTERVALSGIPROC) (int interval);
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 class glxGraphicsStateGuardian : public GLGraphicsStateGuardian {
 class glxGraphicsStateGuardian : public GLGraphicsStateGuardian {
 public:
 public:
-#ifdef HAVE_GLXFBCONFIG
   glxGraphicsStateGuardian(const FrameBufferProperties &properties,
   glxGraphicsStateGuardian(const FrameBufferProperties &properties,
                            glxGraphicsStateGuardian *share_with,
                            glxGraphicsStateGuardian *share_with,
+                           int want_hardware,
                            GLXContext context, XVisualInfo *visual,
                            GLXContext context, XVisualInfo *visual,
-                           Display *display, int screen,
-                           GLXFBConfig fbconfig);
-#else
-  glxGraphicsStateGuardian(const FrameBufferProperties &properties,
-                           glxGraphicsStateGuardian *share_with,
-                           GLXContext context, XVisualInfo *visual,
-                           Display *display, int screen);
+                           Display *display, int screen
+#ifdef HAVE_GLXFBCONFIG
+                           , GLXFBConfig fbconfig
 #endif  // HAVE_GLXFBCONFIG
 #endif  // HAVE_GLXFBCONFIG
+                           );
 
 
   virtual ~glxGraphicsStateGuardian();
   virtual ~glxGraphicsStateGuardian();
 
 
@@ -75,6 +72,7 @@ public:
 
 
   bool glx_is_at_least_version(int major_version, int minor_version) const;
   bool glx_is_at_least_version(int major_version, int minor_version) const;
 
 
+  int _want_hardware;
   GLXContext _context;
   GLXContext _context;
   XVisualInfo *_visual;
   XVisualInfo *_visual;
   Display *_display;
   Display *_display;
@@ -89,7 +87,7 @@ public:
   PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
   PFNGLXSWAPINTERVALSGIPROC _glXSwapIntervalSGI;
 
 
 protected:
 protected:
-  virtual void get_gl_version();
+  virtual void query_gl_version();
   virtual void get_extra_extensions();
   virtual void get_extra_extensions();
   virtual void *get_extension_func(const char *prefix, const char *name);
   virtual void *get_extension_func(const char *prefix, const char *name);
 
 

+ 1 - 1
panda/src/glxdisplay/glxGraphicsWindow.cxx

@@ -122,7 +122,7 @@ make_context() {
   // reset() requires having a current context.)
   // reset() requires having a current context.)
   glxgsg->reset_if_new();
   glxgsg->reset_if_new();
 
 
-  return true;
+  return glxgsg->is_valid();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////