Browse Source

Improve shader model detection mechanism

rdb 10 years ago
parent
commit
87b23dfeb2

+ 1 - 0
panda/src/cocoadisplay/cocoaGraphicsPipe.mm

@@ -19,6 +19,7 @@
 #include "cocoaPandaApp.h"
 #include "config_cocoadisplay.h"
 #include "frameBufferProperties.h"
+#include "displayInformation.h"
 
 #import <Foundation/NSAutoreleasePool.h>
 #import <AppKit/NSApplication.h>

+ 4 - 6
panda/src/display/displayInformation.cxx

@@ -90,13 +90,12 @@ DisplayInformation() {
   int window_bits_per_pixel;
   int total_display_modes;
   DisplayMode *display_mode_array;
-  int shader_model;
   int video_memory;
   int texture_memory;
   PN_uint64 physical_memory;
   PN_uint64 available_physical_memory;
 
-  state = DisplayInformation::DS_unknown;    
+  state = DisplayInformation::DS_unknown;
   get_adapter_display_mode_state = false;
   get_device_caps_state = false;
   window_width = 0;
@@ -104,7 +103,6 @@ DisplayInformation() {
   window_bits_per_pixel = 0;
   total_display_modes = 0;
   display_mode_array = NULL;
-  shader_model = GraphicsStateGuardian::SM_00;
   video_memory = 0;
   texture_memory = 0;
   physical_memory = 0;
@@ -118,7 +116,7 @@ DisplayInformation() {
   _window_bits_per_pixel = window_bits_per_pixel;
   _total_display_modes = total_display_modes;
   _display_mode_array = display_mode_array;
-  _shader_model = shader_model;
+  _shader_model = GraphicsStateGuardian::SM_00;
   _video_memory = video_memory;
   _texture_memory = texture_memory;
 
@@ -328,8 +326,8 @@ get_display_mode_fullscreen_only (int display_index) {
 //       Access: Published
 //  Description: 
 ////////////////////////////////////////////////////////////////////
-int DisplayInformation::
-get_shader_model ( ) {
+GraphicsStateGuardian::ShaderModel DisplayInformation::
+get_shader_model() {
   return _shader_model;
 }
 

+ 4 - 3
panda/src/display/displayInformation.h

@@ -16,6 +16,7 @@
 #define DISPLAYINFORMATION_H
 
 #include "typedef.h"
+#include "graphicsStateGuardian.h"
 
 struct EXPCL_PANDA_DISPLAY DisplayMode {
 PUBLISHED:
@@ -65,7 +66,7 @@ PUBLISHED:
   int get_display_mode_refresh_rate(int display_index);
   int get_display_mode_fullscreen_only(int display_index);
 
-  int get_shader_model();
+  GraphicsStateGuardian::ShaderModel get_shader_model();
   int get_video_memory();
   int get_texture_memory();
 
@@ -126,9 +127,9 @@ public:
   int _maximum_window_width;
   int _maximum_window_height;
   int _window_bits_per_pixel;
-  int _total_display_modes;  
+  int _total_display_modes;
   DisplayMode *_display_mode_array;
-  int _shader_model;
+  GraphicsStateGuardian::ShaderModel _shader_model;
   int _video_memory;
   int _texture_memory;
 

+ 1 - 0
panda/src/display/graphicsPipe.cxx

@@ -17,6 +17,7 @@
 #include "graphicsBuffer.h"
 #include "config_display.h"
 #include "mutexHolder.h"
+#include "displayInformation.h"
 
 TypeHandle GraphicsPipe::_type_handle;
 

+ 1 - 1
panda/src/display/graphicsPipe.h

@@ -21,7 +21,6 @@
 #include "typedReferenceCount.h"
 #include "pointerTo.h"
 #include "lightMutex.h"
-#include "displayInformation.h"
 
 class GraphicsEngine;
 class GraphicsOutput;
@@ -32,6 +31,7 @@ class FrameBufferProperties;
 class WindowProperties;
 class Texture;
 class WindowHandle;
+class DisplayInformation;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : GraphicsPipe

+ 2 - 2
panda/src/display/graphicsStateGuardian.I

@@ -876,7 +876,7 @@ get_maximum_simultaneous_render_targets() const {
 //       Access: Published
 //  Description: Returns the ShaderModel
 ////////////////////////////////////////////////////////////////////
-INLINE int GraphicsStateGuardian::
+INLINE GraphicsStateGuardian::ShaderModel GraphicsStateGuardian::
 get_shader_model() const {
   return _shader_model;
 }
@@ -889,7 +889,7 @@ get_shader_model() const {
 //               testing lower-end shaders.
 ////////////////////////////////////////////////////////////////////
 INLINE void GraphicsStateGuardian::
-set_shader_model(int shader_model) {
+set_shader_model(ShaderModel shader_model) {
   if (shader_model <= _auto_detect_shader_model) {
     _shader_model = shader_model;
   }

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

@@ -3344,3 +3344,11 @@ int GraphicsStateGuardian::
 get_driver_shader_version_minor() {
   return -1;
 }
+
+ostream &
+operator << (ostream &out, GraphicsStateGuardian::ShaderModel sm) {
+  static const char *sm_strings[] = {"none", "1.1", "2.0", "2.x", "3.0", "4.0", "5.0", "5.1"};
+  nassertr(sm >= 0 && sm <= GraphicsStateGuardian::SM_51, out);
+  out << sm_strings[sm];
+  return out;
+}

+ 7 - 4
panda/src/display/graphicsStateGuardian.h

@@ -83,6 +83,7 @@ PUBLISHED:
     SM_30,
     SM_40,
     SM_50,
+    SM_51,
   };
 
   INLINE void release_all();
@@ -166,8 +167,8 @@ PUBLISHED:
   INLINE int get_max_color_targets() const;
   INLINE int get_maximum_simultaneous_render_targets() const;
 
-  INLINE int get_shader_model() const;
-  INLINE void set_shader_model(int shader_model);
+  INLINE ShaderModel get_shader_model() const;
+  INLINE void set_shader_model(ShaderModel shader_model);
 
   virtual int get_supported_geom_rendering() const;
   virtual bool get_supports_cg_profile(const string &name) const;
@@ -545,8 +546,8 @@ protected:
 
   int  _stereo_buffer_mask;
 
-  int _auto_detect_shader_model;
-  int _shader_model;
+  ShaderModel _auto_detect_shader_model;
+  ShaderModel _shader_model;
 
   static PT(TextureStage) _alpha_scale_texture_stage;
 
@@ -664,6 +665,8 @@ private:
   friend class GraphicsEngine;
 };
 
+EXPCL_PANDA_DISPLAY ostream &operator << (ostream &out, GraphicsStateGuardian::ShaderModel sm);
+
 #include "graphicsStateGuardian.I"
 
 #endif

+ 57 - 71
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -64,6 +64,7 @@
 #include "graphicsEngine.h"
 #include "shaderGenerator.h"
 #include "samplerState.h"
+#include "displayInformation.h"
 
 #if defined(HAVE_CG) && !defined(OPENGLES)
 #include "Cg/cgGL.h"
@@ -2450,58 +2451,39 @@ reset() {
 
   report_my_gl_errors();
 
-#if defined(HAVE_CG) && !defined(OPENGLES)
-
-  typedef struct {
-    CGprofile cg_profile;
-    int shader_model;
-  } CG_PROFILE_TO_SHADER_MODEL;
-
-  static CG_PROFILE_TO_SHADER_MODEL cg_profile_to_shader_model_array[] = {
+#ifndef OPENGLES
+  if (_gl_shadlang_ver_major >= 4 || has_extension("GL_NV_gpu_program5")) {
     // gp5fp - OpenGL fragment profile for GeForce 400 Series and up
-    (CGprofile)7017, /*CG_PROFILE_GP5FP,*/
-    SM_50,
+    _shader_model = SM_50;
 
+  } else if (_gl_shadlang_ver_major >= 3 ||
+             has_extension("GL_NV_gpu_program4")) {
     // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up)
-    (CGprofile)7010, /*CG_PROFILE_GP4FP,*/
-    SM_40,
+    _shader_model = SM_40;
 
+  } else if (has_extension("GL_NV_fragment_program2")) {
     // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx
     // Series, NV4x-based Quadro FX, etc.)
-    CG_PROFILE_FP40,
-    SM_30,
+    _shader_model = SM_30;
 
+  } else if (has_extension("GL_NV_fragment_program")) {
     // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
-    CG_PROFILE_FP30,
-    SM_2X,
+    _shader_model = SM_2X;
 
+  } else if (_gl_shadlang_ver_major >= 1 ||
+             has_extension("GL_ARB_fragment_program")) {
     // This OpenGL profile corresponds to the per-fragment
-    // functionality introduced by GeForce FX and other DirectX 9
-    // GPUs.
-    CG_PROFILE_ARBFP1,
-    SM_20,
+    // functionality introduced by GeForce FX and other DirectX 9 GPUs.
+    _shader_model = SM_20;
 
+  } else if (has_extension("GL_NV_texture_shader2")) {
     // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti,
     // Quadro DCC, etc.)
-    CG_PROFILE_FP20,
-    SM_11,
+    _shader_model = SM_11;
 
-    // no shader support
-    CG_PROFILE_UNKNOWN,
-    SM_00,
-  };
-
-  int index;
-  CG_PROFILE_TO_SHADER_MODEL *cg_profile_to_shader_model;
-
-  index = 0;
-  cg_profile_to_shader_model = cg_profile_to_shader_model_array;
-  while (cg_profile_to_shader_model->shader_model != SM_00) {
-    if (cgGLIsProfileSupported(cg_profile_to_shader_model->cg_profile)) {
-      _shader_model = cg_profile_to_shader_model->shader_model;
-      break;
-    }
-    cg_profile_to_shader_model++;
+  } else {
+    // No shader support
+    _shader_model = SM_00;
   }
 
   // DisplayInformation may have better shader model detection
@@ -2521,12 +2503,8 @@ reset() {
   }
   _auto_detect_shader_model = _shader_model;
 
-  CGprofile vertex_profile;
-  CGprofile pixel_profile;
-
-  vertex_profile = cgGLGetLatestProfile(CG_GL_VERTEX);
-  pixel_profile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
   if (GLCAT.is_debug()) {
+#ifdef HAVE_CG
 #if CG_VERSION_NUM >= 2200
     GLCAT.debug() << "Supported Cg profiles:\n";
     int num_profiles = cgGetNumSupportedProfiles();
@@ -2539,21 +2517,24 @@ reset() {
 #endif  // CG_VERSION_NUM >= 2200
 
 #if CG_VERSION_NUM >= 3100
-    if (GLCAT.is_debug()) {
-      CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context);
-      GLCAT.debug()
-        << "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n";
-    }
+    CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context);
+    GLCAT.debug()
+      << "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n";
 #endif
 
+    CGprofile vertex_profile = cgGLGetLatestProfile(CG_GL_VERTEX);
+    CGprofile pixel_profile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
     GLCAT.debug()
-      << "\nCg latest vertex profile = " << cgGetProfileString(vertex_profile) << "  id = " << vertex_profile
-      << "\nCg latest pixel profile = " << cgGetProfileString(pixel_profile) << "  id = " << pixel_profile
-      << "\nshader model = " << _shader_model
-      << "\n";
-  }
+      << "Cg latest vertex profile = " << cgGetProfileString(vertex_profile)
+      << " (" << vertex_profile << ")\n";
+    GLCAT.debug()
+      << "Cg latest pixel profile = " << cgGetProfileString(pixel_profile)
+      << " (" << pixel_profile << ")\n";
+#endif  // HAVE_CG
 
-#endif
+    GLCAT.debug() << "shader model = " << _shader_model << "\n";
+  }
+#endif  // !OPENGLES
 
   // OpenGL core profile requires a VAO to be bound.  It's a bit silly,
   // because we can just bind a VAO and then forget about it.
@@ -6872,7 +6853,6 @@ query_gl_version() {
       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.
@@ -6890,6 +6870,7 @@ query_gl_version() {
       return;
     }
   }
+#endif  // !OPENGLES
 
   // Otherwise, parse the GL_VERSION string.
   if (_gl_version.empty()) {
@@ -6946,31 +6927,36 @@ query_glsl_version() {
   _gl_shadlang_ver_minor = 0;
 
 #ifndef OPENGLES
-  if (_gl_version_major == 1) {
-    if (has_extension("GL_ARB_shading_language_100")) {
-      _gl_shadlang_ver_major = 1;
-      _gl_shadlang_ver_minor = 0;
-    }
-  } else if (_gl_version_major >= 2) {
+  // OpenGL 2.0 introduces GLSL in the core.  In 1.x, it is an extension.
+  if (_gl_version_major >= 2 || has_extension("GL_ARB_shading_language_100")) {
+    string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
     _gl_shadlang_ver_major = 1;
-    _gl_shadlang_ver_minor = 1;
-    const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
-    if (verstr == NULL ||
-        sscanf(verstr, "%d.%d", &_gl_shadlang_ver_major,
-                                &_gl_shadlang_ver_minor) != 2) {
+    _gl_shadlang_ver_minor = (_gl_version_major >= 2) ? 1 : 0;
+    if (ver.empty() ||
+        sscanf(ver.c_str(), "%d.%d", &_gl_shadlang_ver_major,
+                                     &_gl_shadlang_ver_minor) != 2) {
       GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
     }
   }
-#elif defined(OPENGLES_2)
+#elif !defined(OPENGLES_1)
+  // OpenGL ES 2.0 and above has shader support built-in.
+  string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
   _gl_shadlang_ver_major = 1;
   _gl_shadlang_ver_minor = 0;
-  const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
-  if (verstr == NULL ||
-      sscanf(verstr, "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major,
-                                             &_gl_shadlang_ver_minor) != 2) {
+  if (ver.empty() ||
+      sscanf(ver.c_str(), "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major,
+                                                  &_gl_shadlang_ver_minor) != 2) {
     GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
   }
 #endif
+
+#ifndef OPENGLES_1
+  if (GLCAT.is_debug()) {
+    GLCAT.debug()
+      << "Detected GLSL version: "
+      << _gl_shadlang_ver_major << "." << _gl_shadlang_ver_minor << "\n";
+  }
+#endif
 }
 
 ////////////////////////////////////////////////////////////////////

+ 1 - 0
panda/src/osxdisplay/osxGraphicsPipe.cxx

@@ -17,6 +17,7 @@
 #include "pnmImage.h"
 #include "subprocessWindow.h"
 #include "nativeWindowHandle.h"
+#include "displayInformation.h"
 #import <Carbon/Carbon.h>
 
 // some macros to make code more readable.

+ 2 - 1
panda/src/windisplay/winDetectDx.h

@@ -13,6 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 
 #include <time.h>
+#include "displayInformation.h"
 
 typedef struct {
   D3DFORMAT d3d_format;
@@ -116,7 +117,7 @@ static int get_display_information (DisplaySearchParameters &display_search_para
   int get_adapter_display_mode_state;
   int get_device_caps_state;
 
-  int shader_model;
+  GraphicsStateGuardian::ShaderModel shader_model;
   UINT minimum_width;
   UINT maximum_width;
   UINT minimum_height;

+ 1 - 0
panda/src/x11display/x11GraphicsPipe.cxx

@@ -16,6 +16,7 @@
 #include "x11GraphicsWindow.h"
 #include "config_x11display.h"
 #include "frameBufferProperties.h"
+#include "displayInformation.h"
 
 TypeHandle x11GraphicsPipe::_type_handle;