Browse Source

Add new profile override system

rdb 16 years ago
parent
commit
4034d97417
2 changed files with 78 additions and 1 deletions
  1. 71 1
      panda/src/gobj/shader.cxx
  2. 7 0
      panda/src/gobj/shader.h

+ 71 - 1
panda/src/gobj/shader.cxx

@@ -1040,6 +1040,7 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, bool fshader)
   CGerror err;
   CGerror err;
   const char *compiler_args[100];
   const char *compiler_args[100];
   int nargs = 0;
   int nargs = 0;
+  int override = fshader ? _cg_fprofile : _cg_vprofile;
   int active = fshader ? caps._active_fprofile : caps._active_vprofile;
   int active = fshader ? caps._active_fprofile : caps._active_vprofile;
   int ultimate = fshader ? caps._ultimate_fprofile : caps._ultimate_vprofile;
   int ultimate = fshader ? caps._ultimate_fprofile : caps._ultimate_vprofile;
 
 
@@ -1051,6 +1052,26 @@ cg_compile_entry_point(const char *entry, const ShaderCaps &caps, bool fshader)
   }
   }
   compiler_args[nargs] = 0;
   compiler_args[nargs] = 0;
 
 
+  // If someone has explicitly set a profile, use it.
+  if (override != (int)CG_PROFILE_UNKNOWN) {
+    prog = cgCreateProgram(_cg_context, CG_SOURCE, _text.c_str(),
+                           (CGprofile)override, entry, (const char **)compiler_args);
+    if (cgGetError() == CG_NO_ERROR) {
+      return prog;
+    }
+    if (prog != 0) {
+      cgDestroyProgram(prog);
+    }
+    if (fshader) {
+      gobj_cat.error() << "Fragment shader failed to compile with profile '"
+        << cgGetProfileString((CGprofile)override) << "!\n";
+    } else {
+      gobj_cat.error() << "Vertex shader failed to compile with profile '"
+        << cgGetProfileString((CGprofile)override) << "!\n";
+    }
+    return 0;
+  }
+  
   if ((active != (int)CG_PROFILE_UNKNOWN) && (active != ultimate)) {
   if ((active != (int)CG_PROFILE_UNKNOWN) && (active != ultimate)) {
     prog = cgCreateProgram(_cg_context, CG_SOURCE, _text.c_str(),
     prog = cgCreateProgram(_cg_context, CG_SOURCE, _text.c_str(),
                            (CGprofile)active, entry, (const char **)compiler_args);
                            (CGprofile)active, entry, (const char **)compiler_args);
@@ -1353,7 +1374,8 @@ cg_compile_for(const ShaderCaps &caps,
   
   
   if ((cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile)||
   if ((cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile)||
       (cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile)) {
       (cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile)) {
-    gobj_cat.error() << "Cg program too complex for driver:" << get_filename() << "\n";
+    gobj_cat.error() << "Cg program too complex for driver:"
+      << get_filename() << ". Try choosing a different profile.\n";
     return false;
     return false;
   }
   }
   
   
@@ -1424,6 +1446,8 @@ Shader(const Filename &filename, const string &text) :
   _cg_context = 0;
   _cg_context = 0;
   _cg_vprogram = 0;
   _cg_vprogram = 0;
   _cg_fprogram = 0;
   _cg_fprogram = 0;
+  _cg_vprofile = CG_PROFILE_UNKNOWN;
+  _cg_fprofile = CG_PROFILE_UNKNOWN;
   if (_default_caps._ultimate_vprofile == 0) {
   if (_default_caps._ultimate_vprofile == 0) {
     _default_caps._active_vprofile = CG_PROFILE_UNKNOWN;
     _default_caps._active_vprofile = CG_PROFILE_UNKNOWN;
     _default_caps._active_fprofile = CG_PROFILE_UNKNOWN;
     _default_caps._active_fprofile = CG_PROFILE_UNKNOWN;
@@ -1618,6 +1642,52 @@ parse_eof() {
   return (int)_text.size() == _parse;
   return (int)_text.size() == _parse;
 }
 }
 
 
+#ifdef HAVE_CG
+////////////////////////////////////////////////////////////////////
+//     Function: Shader::set_vertex_profile
+//       Access: Published
+//  Description: Sets the profile for the vertex shader. This
+//               overrides all other profile settings (it even
+//               overrides basic-shaders-only) and forces the shader
+//               to use the given profile. If that fails, it will
+//               throw an error.
+////////////////////////////////////////////////////////////////////
+void Shader::
+set_vertex_profile(const string &profile) {
+  if (profile.empty()) {
+    _cg_vprofile = CG_PROFILE_UNKNOWN;
+    return;
+  }
+  CGprofile p = cgGetProfile(profile.c_str());
+  if (p == CG_PROFILE_UNKNOWN) {
+    gobj_cat.error() << "Invalid vertex profile: " << profile << "\n";
+  }
+  _cg_vprofile = p;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Shader::set_fragment_profile
+//       Access: Published
+//  Description: Sets the profile for the vertex shader. This
+//               overrides all other profile settings (it even
+//               overrides basic-shaders-only) and forces the shader
+//               to use the given profile. If that fails, it will
+//               throw an error.
+////////////////////////////////////////////////////////////////////
+void Shader::
+set_fragment_profile(const string &profile) {
+  if (profile.empty()) {
+    _cg_fprofile = CG_PROFILE_UNKNOWN;
+    return;
+  }
+  CGprofile p = cgGetProfile(profile.c_str());
+  if (p == CG_PROFILE_UNKNOWN) {
+    gobj_cat.error() << "Invalid fragment profile: " << profile << "\n";
+  }
+  _cg_fprofile = p;
+}
+#endif
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Shader::prepare
 //     Function: Shader::prepare
 //       Access: Published
 //       Access: Published

+ 7 - 0
panda/src/gobj/shader.h

@@ -51,6 +51,11 @@ PUBLISHED:
   INLINE static void set_shader_utilization(ShaderUtilization utl);
   INLINE static void set_shader_utilization(ShaderUtilization utl);
   INLINE static bool have_shader_utilization();
   INLINE static bool have_shader_utilization();
   
   
+#ifdef HAVE_CG
+  void set_vertex_profile(const string &profile);
+  void set_fragment_profile(const string &profile);
+#endif
+  
   void prepare(PreparedGraphicsObjects *prepared_objects);
   void prepare(PreparedGraphicsObjects *prepared_objects);
   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
   bool release(PreparedGraphicsObjects *prepared_objects);
   bool release(PreparedGraphicsObjects *prepared_objects);
@@ -268,6 +273,8 @@ public:
   CGcontext  _cg_context;
   CGcontext  _cg_context;
   CGprogram  _cg_vprogram;
   CGprogram  _cg_vprogram;
   CGprogram  _cg_fprogram;
   CGprogram  _cg_fprogram;
+  int        _cg_vprofile;
+  int        _cg_fprofile;
   
   
  public:
  public: