瀏覽代碼

shaderpipeline: Get Cg shaders working again

Mitchell Stokes 6 年之前
父節點
當前提交
d9d6e6629a
共有 3 個文件被更改,包括 96 次插入82 次删除
  1. 92 79
      panda/src/gobj/shader.cxx
  2. 3 2
      panda/src/shaderpipeline/shaderCompilerCg.cxx
  3. 1 1
      panda/src/shaderpipeline/shaderCompilerCg.h

+ 92 - 79
panda/src/gobj/shader.cxx

@@ -45,8 +45,18 @@ int Shader::_shaders_generated;
 
 #ifdef HAVE_CG
 CGcontext Shader::_cg_context = 0;
+
 #endif
 
+/**
+ * Determine whether the source file hints at being a Cg shader
+ */
+static bool has_cg_header(const std::string &shader_text) {
+  size_t newline_pos = shader_text.find('\n');
+  std::string search_str = shader_text.substr(0, newline_pos);
+  return search_str.rfind("//Cg") != std::string::npos;
+}
+
 /**
  * Generate an error message including a description of the specified
  * parameter.
@@ -2423,45 +2433,6 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
     }
     _fullpath = _source_files[0];
     _filename = sfile;
-
-    // Determine which language the shader is written in.
-    if (_language == SL_none) {
-      string header;
-      parse_init();
-      parse_line(header, true, true);
-      if (header == "//Cg") {
-        _language = SL_Cg;
-      } else {
-        shader_cat.error()
-          << "Unable to determine shader language of " << sfile._shared << "\n";
-        return false;
-      }
-    } else if (_language == SL_GLSL) {
-      shader_cat.error()
-        << "GLSL shaders must have separate shader bodies!\n";
-      return false;
-    }
-
-    // Determine which language the shader is written in.
-    if (_language == SL_Cg) {
-#ifdef HAVE_CG
-      ShaderCompilerCg *cg_compiler = DCAST(ShaderCompilerCg, get_compiler(SL_Cg));
-      cg_compiler->get_profile_from_header(_text, _default_caps);
-
-      if (!cg_analyze_shader(_default_caps)) {
-        shader_cat.error()
-          << "Shader encountered an error.\n";
-        return false;
-      }
-#else
-      shader_cat.error()
-        << "Tried to load Cg shader, but no Cg support is enabled.\n";
-#endif
-    } else {
-      shader_cat.error()
-        << "Shader is not in a supported shader-language.\n";
-      return false;
-    }
   }
 
   _loaded = true;
@@ -2514,45 +2485,6 @@ load(const ShaderFile &sbody, BamCacheRecord *record) {
     if (!do_load_source(Stage::unspecified, sbody._shared, record)) {
       return false;
     }
-
-    // Determine which language the shader is written in.
-    if (_language == SL_none) {
-      string header;
-      parse_init();
-      parse_line(header, true, true);
-      if (header == "//Cg") {
-        _language = SL_Cg;
-      } else {
-        shader_cat.error()
-          << "Unable to determine shader language of " << sbody._shared << "\n";
-        return false;
-      }
-    } else if (_language == SL_GLSL) {
-      shader_cat.error()
-        << "GLSL shaders must have separate shader bodies!\n";
-      return false;
-    }
-
-    // Determine which language the shader is written in.
-    if (_language == SL_Cg) {
-#ifdef HAVE_CG
-      ShaderCompilerCg *cg_compiler = DCAST(ShaderCompilerCg, get_compiler(SL_Cg));
-      cg_compiler->get_profile_from_header(_text, _default_caps);
-
-      if (!cg_analyze_shader(_default_caps)) {
-        shader_cat.error()
-          << "Shader encountered an error.\n";
-        return false;
-      }
-#else
-      shader_cat.error()
-        << "Tried to load Cg shader, but no Cg support is enabled.\n";
-#endif
-    } else {
-      shader_cat.error()
-        << "Shader is not in a supported shader-language.\n";
-      return false;
-    }
   }
 
   _loaded = true;
@@ -2579,6 +2511,30 @@ do_read_source(Stage stage, const Filename &fn, BamCacheRecord *record) {
   module->set_source_filename(fn);
   std::string &into = module->_raw_source;
 
+  if (stage == Stage::unspecified) {
+    // Determine which language the shader is written in.
+    if (_language == SL_none) {
+      if (has_cg_header(into)) {
+        _language = SL_Cg;
+      } else {
+        shader_cat.error()
+          << "Unable to determine shader language of " << fn << "\n";
+        return false;
+      }
+    } else if (_language == SL_GLSL) {
+      shader_cat.error()
+        << "GLSL shaders must have separate shader bodies!\n";
+      return false;
+    }
+
+    if (_language != SL_Cg) {
+      shader_cat.error()
+        << "Shader is not in a supported shader-language.\n";
+      return false;
+    }
+
+  }
+
   if (_language == SL_GLSL && glsl_preprocess) {
     istream *source = vf->open_read_file(true);
     if (source == nullptr) {
@@ -2599,7 +2555,6 @@ do_read_source(Stage stage, const Filename &fn, BamCacheRecord *record) {
     }
     vf->close_read_file(source);
     into = sstr.str();
-
   } else {
     shader_cat.info() << "Reading shader file: " << fn << "\n";
 
@@ -2610,6 +2565,23 @@ do_read_source(Stage stage, const Filename &fn, BamCacheRecord *record) {
     }
   }
 
+  if (_language == SL_Cg) {
+#ifdef HAVE_CG
+    ShaderCompilerCg *cg_compiler = DCAST(ShaderCompilerCg, get_compiler(SL_Cg));
+    cg_compiler->get_profile_from_header(into, _default_caps);
+
+    _text._shared = into;
+    if (!cg_analyze_shader(_default_caps)) {
+      shader_cat.error()
+        << "Shader encountered an error.\n";
+      return false;
+    }
+#else
+    shader_cat.error()
+      << "Tried to load Cg shader, but no Cg support is enabled.\n";
+#endif
+  }
+
   if (record != nullptr) {
     record->add_dependent_file(vf);
   }
@@ -2643,6 +2615,30 @@ do_load_source(ShaderModule::Stage stage, const std::string &source, BamCacheRec
   PT(ShaderModuleGlsl) module = new ShaderModuleGlsl(stage);
   std::string &into = module->_raw_source;
 
+  if (stage == Stage::unspecified) {
+    // Determine which language the shader is written in.
+    if (_language == SL_none) {
+      if (has_cg_header(source)) {
+        _language = SL_Cg;
+      } else {
+        shader_cat.error()
+          << "Unable to determine shader language of " << source << "\n";
+        return false;
+      }
+    } else if (_language == SL_GLSL) {
+      shader_cat.error()
+        << "GLSL shaders must have separate shader bodies!\n";
+      return false;
+    }
+
+    if (_language != SL_Cg) {
+      shader_cat.error()
+        << "Shader is not in a supported shader-language.\n";
+      return false;
+    }
+
+  }
+
   if (_language == SL_GLSL && glsl_preprocess) {
     // Preprocess the GLSL file as we read it.
     std::set<Filename> open_files;
@@ -2658,6 +2654,23 @@ do_load_source(ShaderModule::Stage stage, const std::string &source, BamCacheRec
     into = source;
   }
 
+  if (_language == SL_Cg) {
+#ifdef HAVE_CG
+    ShaderCompilerCg *cg_compiler = DCAST(ShaderCompilerCg, get_compiler(SL_Cg));
+    cg_compiler->get_profile_from_header(into, _default_caps);
+
+    _text._shared = into;
+    if (!cg_analyze_shader(_default_caps)) {
+      shader_cat.error()
+        << "Shader encountered an error.\n";
+      return false;
+    }
+#else
+    shader_cat.error()
+      << "Tried to load Cg shader, but no Cg support is enabled.\n";
+#endif
+  }
+
   // Strip trailing whitespace.
   while (!into.empty() && isspace(into[into.size() - 1])) {
     into.resize(into.size() - 1);

+ 3 - 2
panda/src/shaderpipeline/shaderCompilerCg.cxx

@@ -76,11 +76,10 @@ ShaderCompilerCg() {
  * profile directives stored within the shader header
  */
 void ShaderCompilerCg::
-get_profile_from_header(const Shader::ShaderFile &shader_file, Shader::ShaderCaps &caps) const {
+get_profile_from_header(const std::string &shader_text, Shader::ShaderCaps &caps) const {
   // Note this forces profile based on what is specified in the shader header
   // string.  Should probably be relying on card caps eventually.
 #ifdef HAVE_CG
-  std::string shader_text = shader_file._shared;
   size_t last_profile_pos = 0;
   while ((last_profile_pos = shader_text.find("//Cg profile", last_profile_pos)) != std::string::npos) {
     size_t newline_pos = shader_text.find('\n', last_profile_pos);
@@ -106,6 +105,8 @@ get_profile_from_header(const Shader::ShaderFile &shader_file, Shader::ShaderCap
         caps._active_gprofile = cgGetProfile(profile.c_str());
       }
     }
+
+    last_profile_pos = newline_pos;
   }
 #endif // HAVE_CG
 }

+ 1 - 1
panda/src/shaderpipeline/shaderCompilerCg.h

@@ -26,7 +26,7 @@ class EXPCL_PANDA_SHADERPIPELINE ShaderCompilerCg : public ShaderCompiler {
 public:
   ShaderCompilerCg();
 
-  void get_profile_from_header(const Shader::ShaderFile &shader_file, Shader::ShaderCaps &caps) const;
+  void get_profile_from_header(const std::string &shader_text, Shader::ShaderCaps &caps) const;
 
 PUBLISHED:
   virtual std::string get_name() const override;