Browse Source

shader: work on shader modules, get legacy GLSL modules to work

rdb 6 years ago
parent
commit
ca9507c828

+ 52 - 81
panda/src/glstuff/glShaderContext_src.cxx

@@ -26,6 +26,7 @@
 #include "lightAttrib.h"
 #include "lightAttrib.h"
 #include "clipPlaneAttrib.h"
 #include "clipPlaneAttrib.h"
 #include "bamCache.h"
 #include "bamCache.h"
+#include "shaderModuleGlsl.h"
 
 
 using std::dec;
 using std::dec;
 using std::hex;
 using std::hex;
@@ -2949,7 +2950,7 @@ update_shader_buffer_bindings(ShaderContext *prev) {
  * This subroutine prints the infolog for a shader.
  * This subroutine prints the infolog for a shader.
  */
  */
 void CLP(ShaderContext)::
 void CLP(ShaderContext)::
-glsl_report_shader_errors(GLuint shader, Shader::ShaderType type, bool fatal) {
+glsl_report_shader_errors(GLuint shader, const ShaderModuleGlsl *module, bool fatal) {
   char *info_log;
   char *info_log;
   GLint length = 0;
   GLint length = 0;
   GLint num_chars  = 0;
   GLint num_chars  = 0;
@@ -2979,14 +2980,14 @@ glsl_report_shader_errors(GLuint shader, Shader::ShaderType type, bool fatal) {
     if (sscanf(line.c_str(), "ERROR: %d:%d: %n", &fileno, &lineno, &prefixlen) == 2
     if (sscanf(line.c_str(), "ERROR: %d:%d: %n", &fileno, &lineno, &prefixlen) == 2
         && prefixlen > 0) {
         && prefixlen > 0) {
 
 
-      Filename fn = _shader->get_filename_from_index(fileno, type);
+      Filename fn = module->get_filename_from_index(fileno);
       GLCAT.error(false)
       GLCAT.error(false)
         << "ERROR: " << fn << ":" << lineno << ": " << (line.c_str() + prefixlen) << "\n";
         << "ERROR: " << fn << ":" << lineno << ": " << (line.c_str() + prefixlen) << "\n";
 
 
     } else if (sscanf(line.c_str(), "WARNING: %d:%d: %n", &fileno, &lineno, &prefixlen) == 2
     } else if (sscanf(line.c_str(), "WARNING: %d:%d: %n", &fileno, &lineno, &prefixlen) == 2
                && prefixlen > 0) {
                && prefixlen > 0) {
 
 
-      Filename fn = _shader->get_filename_from_index(fileno, type);
+      Filename fn = module->get_filename_from_index(fileno);
       GLCAT.warning(false)
       GLCAT.warning(false)
         << "WARNING: " << fn << ":" << lineno << ": " << (line.c_str() + prefixlen) << "\n";
         << "WARNING: " << fn << ":" << lineno << ": " << (line.c_str() + prefixlen) << "\n";
 
 
@@ -2994,7 +2995,7 @@ glsl_report_shader_errors(GLuint shader, Shader::ShaderType type, bool fatal) {
                && prefixlen > 0) {
                && prefixlen > 0) {
 
 
       // This is the format NVIDIA uses.
       // This is the format NVIDIA uses.
-      Filename fn = _shader->get_filename_from_index(fileno, type);
+      Filename fn = module->get_filename_from_index(fileno);
       GLCAT.error(false)
       GLCAT.error(false)
         << fn << "(" << lineno << ") : " << (line.c_str() + prefixlen) << "\n";
         << fn << "(" << lineno << ") : " << (line.c_str() + prefixlen) << "\n";
 
 
@@ -3002,7 +3003,7 @@ glsl_report_shader_errors(GLuint shader, Shader::ShaderType type, bool fatal) {
                && prefixlen > 0) {
                && prefixlen > 0) {
 
 
       // This is the format for Mesa's OpenGL ES 2 implementation.
       // This is the format for Mesa's OpenGL ES 2 implementation.
-      Filename fn = _shader->get_filename_from_index(fileno, type);
+      Filename fn = module->get_filename_from_index(fileno);
       GLCAT.error(false)
       GLCAT.error(false)
         << fn << ":" << lineno << "(" << colno << "): " << (line.c_str() + prefixlen) << "\n";
         << fn << ":" << lineno << "(" << colno << "): " << (line.c_str() + prefixlen) << "\n";
 
 
@@ -3045,65 +3046,66 @@ glsl_report_program_errors(GLuint program, bool fatal) {
 }
 }
 
 
 /**
 /**
- *
+ * Compiles the given ShaderModuleGlsl and attaches it to the program.
  */
  */
 bool CLP(ShaderContext)::
 bool CLP(ShaderContext)::
-glsl_compile_shader(Shader::ShaderType type) {
-  static const char *types[] = {"", "vertex ", "fragment ", "geometry ",
-      "tessellation control ", "tessellation evaluation ", "compute ", ""};
-
+glsl_compile_shader(const ShaderModule *module) {
+  ShaderModule::Stage stage = module->get_stage();
   if (GLCAT.is_debug()) {
   if (GLCAT.is_debug()) {
     GLCAT.debug()
     GLCAT.debug()
-      << "Compiling GLSL " << types[type] << "shader "
-      << _shader->get_filename(type) << "\n";
+      << "Compiling GLSL " << stage << " shader "
+      << module->get_source_filename() << "\n";
   }
   }
 
 
+  const ShaderModuleGlsl *glsl_module;
+  DCAST_INTO_R(glsl_module, module, false);
+
   GLuint handle = 0;
   GLuint handle = 0;
-  switch (type) {
-    case Shader::ST_vertex:
-      handle = _glgsg->_glCreateShader(GL_VERTEX_SHADER);
-      break;
-    case Shader::ST_fragment:
-      handle = _glgsg->_glCreateShader(GL_FRAGMENT_SHADER);
-      break;
+  switch (stage) {
+  case ShaderModule::Stage::vertex:
+    handle = _glgsg->_glCreateShader(GL_VERTEX_SHADER);
+    break;
+  case ShaderModule::Stage::fragment:
+    handle = _glgsg->_glCreateShader(GL_FRAGMENT_SHADER);
+    break;
 #ifndef OPENGLES
 #ifndef OPENGLES
-    case Shader::ST_geometry:
-      if (_glgsg->get_supports_geometry_shaders()) {
-        handle = _glgsg->_glCreateShader(GL_GEOMETRY_SHADER);
-      }
-      break;
-    case Shader::ST_tess_control:
-      if (_glgsg->get_supports_tessellation_shaders()) {
-        handle = _glgsg->_glCreateShader(GL_TESS_CONTROL_SHADER);
-      }
-      break;
-    case Shader::ST_tess_evaluation:
-      if (_glgsg->get_supports_tessellation_shaders()) {
-        handle = _glgsg->_glCreateShader(GL_TESS_EVALUATION_SHADER);
-      }
-      break;
+  case ShaderModule::Stage::geometry:
+    if (_glgsg->get_supports_geometry_shaders()) {
+      handle = _glgsg->_glCreateShader(GL_GEOMETRY_SHADER);
+    }
+    break;
+  case ShaderModule::Stage::tess_control:
+    if (_glgsg->get_supports_tessellation_shaders()) {
+      handle = _glgsg->_glCreateShader(GL_TESS_CONTROL_SHADER);
+    }
+    break;
+  case ShaderModule::Stage::tess_evaluation:
+    if (_glgsg->get_supports_tessellation_shaders()) {
+      handle = _glgsg->_glCreateShader(GL_TESS_EVALUATION_SHADER);
+    }
+    break;
 #endif
 #endif
-    case Shader::ST_compute:
-      if (_glgsg->get_supports_compute_shaders()) {
-        handle = _glgsg->_glCreateShader(GL_COMPUTE_SHADER);
-      }
-      break;
-    default:
-      break;
+  case ShaderModule::Stage::compute:
+    if (_glgsg->get_supports_compute_shaders()) {
+      handle = _glgsg->_glCreateShader(GL_COMPUTE_SHADER);
+    }
+    break;
+  default:
+    break;
   }
   }
   if (!handle) {
   if (!handle) {
     GLCAT.error()
     GLCAT.error()
-      << "Could not create a GLSL " << types[type] << "shader.\n";
+      << "Could not create a GLSL " << stage << " shader.\n";
     _glgsg->report_my_gl_errors();
     _glgsg->report_my_gl_errors();
     return false;
     return false;
   }
   }
 
 
   if (_glgsg->_use_object_labels) {
   if (_glgsg->_use_object_labels) {
-    string name = _shader->get_filename(type);
+    string name = module->get_source_filename();
     _glgsg->_glObjectLabel(GL_SHADER, handle, name.size(), name.data());
     _glgsg->_glObjectLabel(GL_SHADER, handle, name.size(), name.data());
   }
   }
 
 
-  string text_str = _shader->get_text(type);
+  string text_str = module->get_ir();
   const char* text = text_str.c_str();
   const char* text = text_str.c_str();
   _glgsg->_glShaderSource(handle, 1, &text, nullptr);
   _glgsg->_glShaderSource(handle, 1, &text, nullptr);
   _glgsg->_glCompileShader(handle);
   _glgsg->_glCompileShader(handle);
@@ -3112,9 +3114,9 @@ glsl_compile_shader(Shader::ShaderType type) {
 
 
   if (status != GL_TRUE) {
   if (status != GL_TRUE) {
     GLCAT.error()
     GLCAT.error()
-      << "An error occurred while compiling GLSL " << types[type]
-      << "shader " << _shader->get_filename(type) << ":\n";
-    glsl_report_shader_errors(handle, type, true);
+      << "An error occurred while compiling GLSL " << stage
+      << " shader " << module->get_source_filename() << ":\n";
+    glsl_report_shader_errors(handle, glsl_module, true);
     _glgsg->_glDeleteShader(handle);
     _glgsg->_glDeleteShader(handle);
     _glgsg->report_my_gl_errors();
     _glgsg->report_my_gl_errors();
     return false;
     return false;
@@ -3124,7 +3126,7 @@ glsl_compile_shader(Shader::ShaderType type) {
   _glsl_shaders.push_back(handle);
   _glsl_shaders.push_back(handle);
 
 
   // There might be warnings, so report those.
   // There might be warnings, so report those.
-  glsl_report_shader_errors(handle, type, false);
+  glsl_report_shader_errors(handle, glsl_module, false);
 
 
   return true;
   return true;
 }
 }
@@ -3171,39 +3173,8 @@ glsl_compile_and_link() {
 
 
   bool valid = true;
   bool valid = true;
 
 
-  if (!_shader->get_text(Shader::ST_vertex).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_vertex);
-  }
-
-  if (!_shader->get_text(Shader::ST_fragment).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_fragment);
-  }
-
-  // OpenGL ES has no geometry shaders.
-#ifndef OPENGLES
-  if (!_shader->get_text(Shader::ST_geometry).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_geometry);
-
-    // XXX Actually, it turns out that this is unavailable in the core version
-    // of geometry shaders.  Probably no need to bother with it.
-
-    // nassertr(_glgsg->_glProgramParameteri != NULL, false); GLint
-    // max_vertices; glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES,
-    // &max_vertices); _glgsg->_glProgramParameteri(_glsl_program,
-    // GL_GEOMETRY_VERTICES_OUT_ARB, max_vertices);
-  }
-#endif
-
-  if (!_shader->get_text(Shader::ST_tess_control).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_tess_control);
-  }
-
-  if (!_shader->get_text(Shader::ST_tess_evaluation).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_tess_evaluation);
-  }
-
-  if (!_shader->get_text(Shader::ST_compute).empty()) {
-    valid &= glsl_compile_shader(Shader::ST_compute);
+  for (const ShaderModule *module : _shader->_modules) {
+    valid &= glsl_compile_shader(module);
   }
   }
 
 
   // There might be warnings, so report those.  GLSLShaders::const_iterator
   // There might be warnings, so report those.  GLSLShaders::const_iterator

+ 2 - 2
panda/src/glstuff/glShaderContext_src.h

@@ -118,9 +118,9 @@ private:
 
 
   bool _uses_standard_vertex_arrays;
   bool _uses_standard_vertex_arrays;
 
 
-  void glsl_report_shader_errors(GLuint shader, Shader::ShaderType type, bool fatal);
+  void glsl_report_shader_errors(GLuint shader, const ShaderModuleGlsl *module, bool fatal);
   void glsl_report_program_errors(GLuint program, bool fatal);
   void glsl_report_program_errors(GLuint program, bool fatal);
-  bool glsl_compile_shader(Shader::ShaderType type);
+  bool glsl_compile_shader(const ShaderModule *module);
   bool glsl_compile_and_link();
   bool glsl_compile_and_link();
   bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_type, GLint param_size, Shader *s);
   bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_type, GLint param_size, Shader *s);
   void release_resources();
   void release_resources();

+ 2 - 0
panda/src/gobj/shader.I

@@ -84,6 +84,8 @@ set_filename(ShaderType type, const Filename &filename) {
 
 
 /**
 /**
  * Return the Shader's text for the given shader type.
  * Return the Shader's text for the given shader type.
+ *
+ * @deprecated
  */
  */
 INLINE const std::string &Shader::
 INLINE const std::string &Shader::
 get_text(ShaderType type) const {
 get_text(ShaderType type) const {

+ 54 - 60
panda/src/gobj/shader.cxx

@@ -22,6 +22,7 @@
 #include "config_putil.h"
 #include "config_putil.h"
 #include "bamCache.h"
 #include "bamCache.h"
 #include "string_utils.h"
 #include "string_utils.h"
+#include "shaderModuleGlsl.h"
 
 
 #ifdef HAVE_CG
 #ifdef HAVE_CG
 #include <Cg/cg.h>
 #include <Cg/cg.h>
@@ -2408,33 +2409,33 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
     }
     }
 
 
     if (!sfile._vertex.empty() &&
     if (!sfile._vertex.empty() &&
-        !do_read_source(_text._vertex, sfile._vertex, record)) {
+        !do_read_source(Stage::vertex, sfile._vertex, record)) {
       return false;
       return false;
     }
     }
     if (!sfile._fragment.empty() &&
     if (!sfile._fragment.empty() &&
-        !do_read_source(_text._fragment, sfile._fragment, record)) {
+        !do_read_source(Stage::fragment, sfile._fragment, record)) {
       return false;
       return false;
     }
     }
     if (!sfile._geometry.empty() &&
     if (!sfile._geometry.empty() &&
-        !do_read_source(_text._geometry, sfile._geometry, record)) {
+        !do_read_source(Stage::geometry, sfile._geometry, record)) {
       return false;
       return false;
     }
     }
     if (!sfile._tess_control.empty() &&
     if (!sfile._tess_control.empty() &&
-        !do_read_source(_text._tess_control, sfile._tess_control, record)) {
+        !do_read_source(Stage::tess_control, sfile._tess_control, record)) {
       return false;
       return false;
     }
     }
     if (!sfile._tess_evaluation.empty() &&
     if (!sfile._tess_evaluation.empty() &&
-        !do_read_source(_text._tess_evaluation, sfile._tess_evaluation, record)) {
+        !do_read_source(Stage::tess_evaluation, sfile._tess_evaluation, record)) {
       return false;
       return false;
     }
     }
     if (!sfile._compute.empty() &&
     if (!sfile._compute.empty() &&
-        !do_read_source(_text._compute, sfile._compute, record)) {
+        !do_read_source(Stage::compute, sfile._compute, record)) {
       return false;
       return false;
     }
     }
     _filename = sfile;
     _filename = sfile;
 
 
   } else {
   } else {
-    if (!do_read_source(_text._shared, sfile._shared, record)) {
+    if (!do_read_source(Stage::unspecified, sfile._shared, record)) {
       return false;
       return false;
     }
     }
     _fullpath = _source_files[0];
     _fullpath = _source_files[0];
@@ -2501,32 +2502,32 @@ load(const ShaderFile &sbody, BamCacheRecord *record) {
     }
     }
 
 
     if (!sbody._vertex.empty() &&
     if (!sbody._vertex.empty() &&
-        !do_load_source(_text._vertex, sbody._vertex, record)) {
+        !do_load_source(Stage::vertex, sbody._vertex, record)) {
       return false;
       return false;
     }
     }
     if (!sbody._fragment.empty() &&
     if (!sbody._fragment.empty() &&
-        !do_load_source(_text._fragment, sbody._fragment, record)) {
+        !do_load_source(Stage::fragment, sbody._fragment, record)) {
       return false;
       return false;
     }
     }
     if (!sbody._geometry.empty() &&
     if (!sbody._geometry.empty() &&
-        !do_load_source(_text._geometry, sbody._geometry, record)) {
+        !do_load_source(Stage::geometry, sbody._geometry, record)) {
       return false;
       return false;
     }
     }
     if (!sbody._tess_control.empty() &&
     if (!sbody._tess_control.empty() &&
-        !do_load_source(_text._tess_control, sbody._tess_control, record)) {
+        !do_load_source(Stage::tess_control, sbody._tess_control, record)) {
       return false;
       return false;
     }
     }
     if (!sbody._tess_evaluation.empty() &&
     if (!sbody._tess_evaluation.empty() &&
-        !do_load_source(_text._tess_evaluation, sbody._tess_evaluation, record)) {
+        !do_load_source(Stage::tess_evaluation, sbody._tess_evaluation, record)) {
       return false;
       return false;
     }
     }
     if (!sbody._compute.empty() &&
     if (!sbody._compute.empty() &&
-        !do_load_source(_text._compute, sbody._compute, record)) {
+        !do_load_source(Stage::compute, sbody._compute, record)) {
       return false;
       return false;
     }
     }
 
 
   } else {
   } else {
-    if (!do_load_source(_text._shared, sbody._shared, record)) {
+    if (!do_load_source(Stage::unspecified, sbody._shared, record)) {
       return false;
       return false;
     }
     }
 
 
@@ -2580,7 +2581,7 @@ load(const ShaderFile &sbody, BamCacheRecord *record) {
  * it 'invalid'.
  * it 'invalid'.
  */
  */
 bool Shader::
 bool Shader::
-do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
+do_read_source(Stage stage, const Filename &fn, BamCacheRecord *record) {
   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
   PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
   PT(VirtualFile) vf = vfs->find_file(fn, get_model_path());
   if (vf == nullptr) {
   if (vf == nullptr) {
@@ -2589,6 +2590,10 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
     return false;
     return false;
   }
   }
 
 
+  PT(ShaderModuleGlsl) module = new ShaderModuleGlsl(stage);
+  module->set_source_filename(fn);
+  std::string &into = module->_raw_source;
+
   if (_language == SL_GLSL && glsl_preprocess) {
   if (_language == SL_GLSL && glsl_preprocess) {
     istream *source = vf->open_read_file(true);
     istream *source = vf->open_read_file(true);
     if (source == nullptr) {
     if (source == nullptr) {
@@ -2603,7 +2608,7 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
 
 
     std::set<Filename> open_files;
     std::set<Filename> open_files;
     ostringstream sstr;
     ostringstream sstr;
-    if (!r_preprocess_source(sstr, *source, fn, vf->get_filename(), open_files, record)) {
+    if (!r_preprocess_source(module, sstr, *source, fn, vf->get_filename(), open_files, record)) {
       vf->close_read_file(source);
       vf->close_read_file(source);
       return false;
       return false;
     }
     }
@@ -2635,6 +2640,9 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
   // Except add back a newline at the end, which is needed by Intel drivers.
   // Except add back a newline at the end, which is needed by Intel drivers.
   into += "\n";
   into += "\n";
 
 
+  module->_raw_source = into;
+  _modules.push_back(std::move(module));
+
   return true;
   return true;
 }
 }
 
 
@@ -2646,13 +2654,16 @@ do_read_source(string &into, const Filename &fn, BamCacheRecord *record) {
  * it 'invalid'.
  * it 'invalid'.
  */
  */
 bool Shader::
 bool Shader::
-do_load_source(string &into, const std::string &source, BamCacheRecord *record) {
+do_load_source(ShaderModule::Stage stage, const std::string &source, BamCacheRecord *record) {
+  PT(ShaderModuleGlsl) module = new ShaderModuleGlsl(stage);
+  std::string &into = module->_raw_source;
+
   if (_language == SL_GLSL && glsl_preprocess) {
   if (_language == SL_GLSL && glsl_preprocess) {
     // Preprocess the GLSL file as we read it.
     // Preprocess the GLSL file as we read it.
     std::set<Filename> open_files;
     std::set<Filename> open_files;
     std::ostringstream sstr;
     std::ostringstream sstr;
     std::istringstream in(source);
     std::istringstream in(source);
-    if (!r_preprocess_source(sstr, in, Filename("created-shader"), Filename(),
+    if (!r_preprocess_source(module, sstr, in, Filename("created-shader"), Filename(),
                              open_files, record)) {
                              open_files, record)) {
       return false;
       return false;
     }
     }
@@ -2670,6 +2681,8 @@ do_load_source(string &into, const std::string &source, BamCacheRecord *record)
   // Except add back a newline at the end, which is needed by Intel drivers.
   // Except add back a newline at the end, which is needed by Intel drivers.
   into += "\n";
   into += "\n";
 
 
+  _modules.push_back(std::move(module));
+
   return true;
   return true;
 }
 }
 
 
@@ -2681,7 +2694,8 @@ do_load_source(string &into, const std::string &source, BamCacheRecord *record)
  * recursive includes.
  * recursive includes.
  */
  */
 bool Shader::
 bool Shader::
-r_preprocess_include(ostream &out, const Filename &fn,
+r_preprocess_include(ShaderModuleGlsl *module,
+                     ostream &out, const Filename &fn,
                      const Filename &source_dir,
                      const Filename &source_dir,
                      std::set<Filename> &once_files,
                      std::set<Filename> &once_files,
                      BamCacheRecord *record, int depth) {
                      BamCacheRecord *record, int depth) {
@@ -2731,19 +2745,19 @@ r_preprocess_include(ostream &out, const Filename &fn,
   // than that, unfortunately.  Don't do this for the top-level file, though.
   // than that, unfortunately.  Don't do this for the top-level file, though.
   // We don't want anything to get in before a potential #version directive.
   // We don't want anything to get in before a potential #version directive.
   int fileno = 0;
   int fileno = 0;
-  fileno = 2048 + _included_files.size();
+  fileno = 2048 + module->_included_files.size();
 
 
   // Write it into the vector so that we can substitute it later when we are
   // Write it into the vector so that we can substitute it later when we are
   // parsing the GLSL error log.  Don't store the full filename because it
   // parsing the GLSL error log.  Don't store the full filename because it
   // would just be too long to display.
   // would just be too long to display.
-  _included_files.push_back(fn);
+  module->_included_files.push_back(fn);
 
 
   if (shader_cat.is_debug()) {
   if (shader_cat.is_debug()) {
     shader_cat.debug()
     shader_cat.debug()
       << "Preprocessing shader include " << fileno << ": " << fn << "\n";
       << "Preprocessing shader include " << fileno << ": " << fn << "\n";
   }
   }
 
 
-  bool result = r_preprocess_source(out, *source, fn, full_fn, once_files, record, fileno, depth);
+  bool result = r_preprocess_source(module, out, *source, fn, full_fn, once_files, record, fileno, depth);
   vf->close_read_file(source);
   vf->close_read_file(source);
   return result;
   return result;
 }
 }
@@ -2756,7 +2770,8 @@ r_preprocess_include(ostream &out, const Filename &fn,
  * recursive includes.
  * recursive includes.
  */
  */
 bool Shader::
 bool Shader::
-r_preprocess_source(ostream &out, istream &in, const Filename &fn,
+r_preprocess_source(ShaderModuleGlsl *module,
+                    ostream &out, istream &in, const Filename &fn,
                     const Filename &full_fn, std::set<Filename> &once_files,
                     const Filename &full_fn, std::set<Filename> &once_files,
                     BamCacheRecord *record, int fileno, int depth) {
                     BamCacheRecord *record, int fileno, int depth) {
 
 
@@ -2890,7 +2905,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
         }
         }
 
 
         // OK, great.  Process the include.
         // OK, great.  Process the include.
-        if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
+        if (!r_preprocess_include(module, out, incfn, source_dir, once_files, record, depth + 1)) {
           // An error occurred.  Pass on the failure.
           // An error occurred.  Pass on the failure.
           shader_cat.error(false) << "included at line "
           shader_cat.error(false) << "included at line "
             << lineno << " of file " << fn << ":\n  " << line << "\n";
             << lineno << " of file " << fn << ":\n  " << line << "\n";
@@ -3021,7 +3036,7 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
 
 
       // OK, great.  Process the include.
       // OK, great.  Process the include.
       Filename source_dir = full_fn.get_dirname();
       Filename source_dir = full_fn.get_dirname();
-      if (!r_preprocess_include(out, incfn, source_dir, once_files, record, depth + 1)) {
+      if (!r_preprocess_include(module, out, incfn, source_dir, once_files, record, depth + 1)) {
         // An error occurred.  Pass on the failure.
         // An error occurred.  Pass on the failure.
         shader_cat.error(false) << "included at line "
         shader_cat.error(false) << "included at line "
           << lineno << " of file " << fn << ":\n  " << line << "\n";
           << lineno << " of file " << fn << ":\n  " << line << "\n";
@@ -3051,8 +3066,8 @@ r_preprocess_source(ostream &out, istream &in, const Filename &fn,
 
 
         // Replace the string line number with an integer.  This is something
         // Replace the string line number with an integer.  This is something
         // we can substitute later when parsing the GLSL log from the driver.
         // we can substitute later when parsing the GLSL log from the driver.
-        fileno = 2048 + _included_files.size();
-        _included_files.push_back(Filename(filestr));
+        fileno = 2048 + module->_included_files.size();
+        module->_included_files.push_back(Filename(filestr));
 
 
         out << "#line " << lineno << " " << fileno << " // " << filestr << "\n";
         out << "#line " << lineno << " " << fileno << " // " << filestr << "\n";
         continue;
         continue;
@@ -3240,27 +3255,6 @@ Shader::
   }*/
   }*/
 }
 }
 
 
-/**
- * Returns the filename of the included shader with the given source file
- * index (as recorded in the #line statement in r_preprocess_source).  We use
- * this to associate error messages with included files.
- */
-Filename Shader::
-get_filename_from_index(int index, ShaderType type) const {
-  if (index == 0) {
-    Filename fn = get_filename(type);
-    if (!fn.empty()) {
-      return fn;
-    }
-  } else if (glsl_preprocess && index >= 2048 &&
-             (index - 2048) < (int)_included_files.size()) {
-    return _included_files[(size_t)index - 2048];
-  }
-  // Must be a mistake.  Quietly put back the integer.
-  string str = format_string(index);
-  return Filename(str);
-}
-
 /**
 /**
  * Loads the shader with the given filename.
  * Loads the shader with the given filename.
  */
  */
@@ -3287,13 +3281,13 @@ load(const Filename &file, ShaderLanguage lang) {
 
 
   _load_table[sfile] = shader;
   _load_table[sfile] = shader;
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       return i->second;
       return i->second;
     }
     }
     _make_table[shader->_text] = shader;
     _make_table[shader->_text] = shader;
-  }
+  }*/
   return shader;
   return shader;
 }
 }
 
 
@@ -3325,13 +3319,13 @@ load(ShaderLanguage lang, const Filename &vertex,
 
 
   _load_table[sfile] = shader;
   _load_table[sfile] = shader;
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       return i->second;
       return i->second;
     }
     }
     _make_table[shader->_text] = shader;
     _make_table[shader->_text] = shader;
-  }
+  }*/
   return shader;
   return shader;
 }
 }
 
 
@@ -3389,13 +3383,13 @@ load_compute(ShaderLanguage lang, const Filename &fn) {
   }
   }
   _load_table[sfile] = shader;
   _load_table[sfile] = shader;
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       return i->second;
       return i->second;
     }
     }
     _make_table[shader->_text] = shader;
     _make_table[shader->_text] = shader;
-  }
+  }*/
 
 
   // It makes little sense to cache the shader before compilation, so we keep
   // It makes little sense to cache the shader before compilation, so we keep
   // the record for when we have the compiled the shader.
   // the record for when we have the compiled the shader.
@@ -3444,7 +3438,7 @@ make(string body, ShaderLanguage lang) {
     return nullptr;
     return nullptr;
   }
   }
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       shader = i->second;
       shader = i->second;
@@ -3452,7 +3446,7 @@ make(string body, ShaderLanguage lang) {
       _make_table[shader->_text] = shader;
       _make_table[shader->_text] = shader;
     }
     }
     _make_table[std::move(sbody)] = shader;
     _make_table[std::move(sbody)] = shader;
-  }
+  }*/
 
 
   if (dump_generated_shaders) {
   if (dump_generated_shaders) {
     ostringstream fns;
     ostringstream fns;
@@ -3506,7 +3500,7 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry,
     return nullptr;
     return nullptr;
   }
   }
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       shader = i->second;
       shader = i->second;
@@ -3514,7 +3508,7 @@ make(ShaderLanguage lang, string vertex, string fragment, string geometry,
       _make_table[shader->_text] = shader;
       _make_table[shader->_text] = shader;
     }
     }
     _make_table[std::move(sbody)] = shader;
     _make_table[std::move(sbody)] = shader;
-  }
+  }*/
 
 
   return shader;
   return shader;
 }
 }
@@ -3550,7 +3544,7 @@ make_compute(ShaderLanguage lang, string body) {
     return nullptr;
     return nullptr;
   }
   }
 
 
-  if (cache_generated_shaders) {
+  /*if (cache_generated_shaders) {
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     ShaderTable::const_iterator i = _make_table.find(shader->_text);
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
     if (i != _make_table.end() && (lang == SL_none || lang == i->second->_language)) {
       shader = i->second;
       shader = i->second;
@@ -3558,7 +3552,7 @@ make_compute(ShaderLanguage lang, string body) {
       _make_table[shader->_text] = shader;
       _make_table[shader->_text] = shader;
     }
     }
     _make_table[std::move(sbody)] = shader;
     _make_table[std::move(sbody)] = shader;
-  }
+  }*/
 
 
   return shader;
   return shader;
 }
 }

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

@@ -34,6 +34,7 @@
 #include "epvector.h"
 #include "epvector.h"
 #include "asyncFuture.h"
 #include "asyncFuture.h"
 #include "bamCacheRecord.h"
 #include "bamCacheRecord.h"
+#include "shaderModule.h"
 
 
 #ifdef HAVE_CG
 #ifdef HAVE_CG
 // I don't want to include the Cg header file into panda as a whole.  Instead,
 // I don't want to include the Cg header file into panda as a whole.  Instead,
@@ -43,11 +44,15 @@ typedef struct _CGprogram   *CGprogram;
 typedef struct _CGparameter *CGparameter;
 typedef struct _CGparameter *CGparameter;
 #endif
 #endif
 
 
+class ShaderModuleGlsl;
+
 /**
 /**
 
 
  */
  */
 class EXPCL_PANDA_GOBJ Shader : public TypedWritableReferenceCount {
 class EXPCL_PANDA_GOBJ Shader : public TypedWritableReferenceCount {
 PUBLISHED:
 PUBLISHED:
+  using Stage = ShaderModule::Stage;
+
   enum ShaderLanguage {
   enum ShaderLanguage {
     SL_none,
     SL_none,
     SL_Cg,
     SL_Cg,
@@ -578,6 +583,9 @@ public:
   bool _error_flag;
   bool _error_flag;
   ShaderFile _text;
   ShaderFile _text;
 
 
+  typedef pvector<PT(ShaderModule)> Modules;
+  Modules _modules;
+
 protected:
 protected:
   ShaderFile _filename;
   ShaderFile _filename;
   Filename _fullpath;
   Filename _fullpath;
@@ -586,7 +594,6 @@ protected:
   ShaderLanguage _language;
   ShaderLanguage _language;
 
 
   typedef pvector<Filename> Filenames;
   typedef pvector<Filename> Filenames;
-  Filenames _included_files;
 
 
   // Stores full paths, and includes the fullpaths of the shaders themselves
   // Stores full paths, and includes the fullpaths of the shaders themselves
   // as well as the includes.
   // as well as the includes.
@@ -619,13 +626,15 @@ private:
 
 
   bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr);
   bool read(const ShaderFile &sfile, BamCacheRecord *record = nullptr);
   bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr);
   bool load(const ShaderFile &sbody, BamCacheRecord *record = nullptr);
-  bool do_read_source(std::string &into, const Filename &fn, BamCacheRecord *record);
-  bool do_load_source(std::string &into, const std::string &source, BamCacheRecord *record);
-  bool r_preprocess_include(std::ostream &out, const Filename &fn,
+  bool do_read_source(ShaderModule::Stage stage, const Filename &fn, BamCacheRecord *record);
+  bool do_load_source(ShaderModule::Stage stage, const std::string &source, BamCacheRecord *record);
+  bool r_preprocess_include(ShaderModuleGlsl *module,
+                            std::ostream &out, const Filename &fn,
                             const Filename &source_dir,
                             const Filename &source_dir,
                             std::set<Filename> &open_files,
                             std::set<Filename> &open_files,
                             BamCacheRecord *record, int depth);
                             BamCacheRecord *record, int depth);
-  bool r_preprocess_source(std::ostream &out, std::istream &in,
+  bool r_preprocess_source(ShaderModuleGlsl *module,
+                           std::ostream &out, std::istream &in,
                            const Filename &fn, const Filename &full_fn,
                            const Filename &fn, const Filename &full_fn,
                            std::set<Filename> &open_files,
                            std::set<Filename> &open_files,
                            BamCacheRecord *record,
                            BamCacheRecord *record,
@@ -636,8 +645,6 @@ private:
 public:
 public:
   ~Shader();
   ~Shader();
 
 
-  Filename get_filename_from_index(int index, ShaderType type) const;
-
 public:
 public:
   static void register_with_read_factory();
   static void register_with_read_factory();
   virtual void write_datagram(BamWriter *manager, Datagram &dg);
   virtual void write_datagram(BamWriter *manager, Datagram &dg);

+ 3 - 1
panda/src/shaderpipeline/shaderCompiler.h

@@ -33,10 +33,12 @@ protected:
 public:
 public:
   virtual ~ShaderCompiler();
   virtual ~ShaderCompiler();
 
 
+  using Stage = ShaderModule::Stage;
+
 PUBLISHED:
 PUBLISHED:
   virtual std::string get_name() const=0;
   virtual std::string get_name() const=0;
   virtual ShaderLanguages get_languages() const=0;
   virtual ShaderLanguages get_languages() const=0;
-  virtual PT(ShaderModule) compile_now(Shader::ShaderType shader_type, std::string source) const=0;
+  virtual PT(ShaderModule) compile_now(Stage stage, std::istream &in) const=0;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {

+ 2 - 2
panda/src/shaderpipeline/shaderCompilerGlslPreProc.cxx

@@ -45,6 +45,6 @@ get_languages() const {
 }
 }
 
 
 PT(ShaderModule) ShaderCompilerGlslPreProc::
 PT(ShaderModule) ShaderCompilerGlslPreProc::
-compile_now(Shader::ShaderType shader_type, std::string source) const {
-  return new ShaderModuleGlsl(shader_type, source);
+compile_now(ShaderModule::Stage stage, std::istream &in) const {
+  return new ShaderModuleGlsl(stage);
 }
 }

+ 8 - 5
panda/src/shaderpipeline/shaderCompilerGlslPreProc.h

@@ -26,9 +26,9 @@ public:
   ShaderCompilerGlslPreProc();
   ShaderCompilerGlslPreProc();
 
 
 PUBLISHED:
 PUBLISHED:
-  virtual std::string get_name() const;
-  virtual ShaderLanguages get_languages() const;
-  virtual PT(ShaderModule) compile_now(Shader::ShaderType shader_type, std::string source) const;
+  virtual std::string get_name() const override;
+  virtual ShaderLanguages get_languages() const override;
+  virtual PT(ShaderModule) compile_now(Stage stage, std::istream &in) const override;
 
 
 public:
 public:
   static TypeHandle get_class_type() {
   static TypeHandle get_class_type() {
@@ -39,10 +39,13 @@ public:
     register_type(_type_handle, "ShaderCompilerGlslPreProc",
     register_type(_type_handle, "ShaderCompilerGlslPreProc",
                   ShaderCompiler::get_class_type());
                   ShaderCompiler::get_class_type());
   }
   }
-  virtual TypeHandle get_type() const {
+  virtual TypeHandle get_type() const override {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() override {
+    init_type();
     return get_class_type();
     return get_class_type();
   }
   }
-  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
 
 
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;

+ 38 - 0
panda/src/shaderpipeline/shaderModule.I

@@ -0,0 +1,38 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file shaderModule.I
+ * @author rdb
+ * @date 2019-03-21
+ */
+
+/**
+ * Returns the stage of the shading pipeline that this shader module is
+ * intended to fill.
+ */
+INLINE ShaderModule::Stage ShaderModule::
+get_stage() const {
+  return _stage;
+}
+
+/**
+ * Returns the original filename that the module was compiled from.  This may
+ * be empty.
+ */
+INLINE const Filename &ShaderModule::
+get_source_filename() const {
+  return _source_filename;
+}
+
+/**
+ * Sets the source filename.
+ */
+INLINE void ShaderModule::
+set_source_filename(const Filename &filename) {
+  _source_filename = filename;
+}

+ 54 - 1
panda/src/shaderpipeline/shaderModule.cxx

@@ -13,10 +13,63 @@
 
 
 #include "shaderModule.h"
 #include "shaderModule.h"
 
 
+TypeHandle ShaderModule::_type_handle;
+
+/**
+ *
+ */
 ShaderModule::
 ShaderModule::
-ShaderModule() {
+ShaderModule(Stage stage) : _stage(stage) {
 }
 }
 
 
+/**
+ *
+ */
 ShaderModule::
 ShaderModule::
 ~ShaderModule() {
 ~ShaderModule() {
 }
 }
+
+/**
+ * Writes the contents of this object to the datagram for shipping out to a
+ * Bam file.
+ */
+void ShaderModule::
+write_datagram(BamWriter *manager, Datagram &dg) {
+  dg.add_uint8((int)_stage);
+  dg.add_string(_source_filename);
+}
+
+/**
+ * This internal function is called by make_from_bam to read in all of the
+ * relevant data from the BamFile for the new ShaderModule.
+ */
+void ShaderModule::
+fillin(DatagramIterator &scan, BamReader *manager) {
+  _stage = (Stage)scan.get_uint8();
+  _source_filename = scan.get_string();
+}
+
+/**
+ * Returns the stage as a string.
+ */
+std::string ShaderModule::
+format_stage(Stage stage) {
+  switch (stage) {
+  case Stage::unspecified:
+    return "unspecified";
+  case Stage::vertex:
+    return "vertex";
+  case Stage::tess_control:
+    return "tess_control";
+  case Stage::tess_evaluation:
+    return "tess_evaluation";
+  case Stage::geometry:
+    return "geometry";
+  case Stage::fragment:
+    return "fragment";
+  case Stage::compute:
+    return "compute";
+  }
+
+  return "**invalid**";
+}

+ 62 - 3
panda/src/shaderpipeline/shaderModule.h

@@ -14,16 +14,75 @@
 #ifndef SHADERMODULE_H
 #ifndef SHADERMODULE_H
 #define SHADERMODULE_H
 #define SHADERMODULE_H
 
 
+#include "typedWritableReferenceCount.h"
+
 /**
 /**
  * This is the base class for the outputs of shaderCompilers
  * This is the base class for the outputs of shaderCompilers
  */
  */
-class EXPCL_PANDA_SHADERPIPELINE ShaderModule : public TypedReferenceCount {
+class EXPCL_PANDA_SHADERPIPELINE ShaderModule : public TypedWritableReferenceCount {
+PUBLISHED:
+  enum class Stage {
+    unspecified,
+    vertex,
+    tess_control,
+    tess_evaluation,
+    geometry,
+    fragment,
+    compute,
+  };
+
 public:
 public:
-  ShaderModule();
+  ShaderModule(Stage stage);
   virtual ~ShaderModule();
   virtual ~ShaderModule();
 
 
+  INLINE Stage get_stage() const;
+
+  INLINE const Filename &get_source_filename() const;
+  INLINE void set_source_filename(const Filename &);
+
+  static std::string format_stage(Stage stage);
+
 PUBLISHED:
 PUBLISHED:
+  MAKE_PROPERTY(stage, get_stage);
+
   virtual std::string get_ir() const=0;
   virtual std::string get_ir() const=0;
-  virtual Shader::ShaderType get_shader_type() const=0;
+
+private:
+  Stage _stage = Stage::unspecified;
+  Filename _source_filename;
+  time_t _source_modified = 0;
+
+public:
+  virtual void write_datagram(BamWriter *manager, Datagram &dg) override;
+
+protected:
+  void fillin(DatagramIterator &scan, BamReader *manager) override;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    TypedWritableReferenceCount::init_type();
+    register_type(_type_handle, "ShaderModule",
+                  TypedWritableReferenceCount::get_class_type());
+  }
+  virtual TypeHandle get_type() const override {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() override {
+    init_type();
+    return get_class_type();
+  }
+
+private:
+  static TypeHandle _type_handle;
 };
 };
+
+INLINE std::ostream &operator << (std::ostream &out, ShaderModule::Stage stage) {
+  return out << ShaderModule::format_stage(stage);
+}
+
+#include "shaderModule.I"
+
 #endif
 #endif

+ 25 - 6
panda/src/shaderpipeline/shaderModuleGlsl.cxx

@@ -12,11 +12,13 @@
  */
  */
 
 
 #include "shaderModuleGlsl.h"
 #include "shaderModuleGlsl.h"
+#include "string_utils.h"
+
+TypeHandle ShaderModuleGlsl::_type_handle;
 
 
 ShaderModuleGlsl::
 ShaderModuleGlsl::
-ShaderModuleGlsl(Shader::ShaderType shader_type, std::string source) :
-  _shader_type(shader_type),
-  _raw_source(source)
+ShaderModuleGlsl(Stage stage) :
+  ShaderModule(stage)
 {
 {
 }
 }
 
 
@@ -29,7 +31,24 @@ get_ir() const {
   return this->_raw_source;
   return this->_raw_source;
 }
 }
 
 
-Shader::ShaderType ShaderModuleGlsl::
-get_shader_type() const {
-  return this->_shader_type;
+/**
+ * Returns the filename of the included shader with the given source file
+ * index (as recorded in the #line statement in r_preprocess_source).  We use
+ * this to associate error messages with included files.
+ */
+Filename ShaderModuleGlsl::
+get_filename_from_index(int index) const {
+  if (index == 0) {
+    Filename fn = get_source_filename();
+    if (!fn.empty()) {
+      return fn;
+    }
+  } else if (glsl_preprocess && index >= 2048 &&
+             (index - 2048) < (int)_included_files.size()) {
+    return _included_files[(size_t)index - 2048];
+  }
+
+  // Must be a mistake.  Quietly put back the integer.
+  std::string str = format_string(index);
+  return Filename(str);
 }
 }

+ 32 - 6
panda/src/shaderpipeline/shaderModuleGlsl.h

@@ -17,19 +17,45 @@
 #include "shader.h"
 #include "shader.h"
 
 
 /**
 /**
- * ShaderModule that contains raw GLSL code
+ * ShaderModule that contains raw, preprocessed GLSL code
  */
  */
-class EXPCL_PANDA_SHADERPIPELINE ShaderModuleGlsl : public ShaderModule {
+class EXPCL_PANDA_SHADERPIPELINE ShaderModuleGlsl final : public ShaderModule {
 public:
 public:
-  ShaderModuleGlsl(Shader::ShaderType shader_type, std::string source);
+  ShaderModuleGlsl(Stage stage);
   virtual ~ShaderModuleGlsl();
   virtual ~ShaderModuleGlsl();
 
 
+  virtual std::string get_ir() const override;
+
+  Filename get_filename_from_index(int index) const;
+
 protected:
 protected:
   Shader::ShaderType _shader_type;
   Shader::ShaderType _shader_type;
   std::string _raw_source;
   std::string _raw_source;
 
 
-PUBLISHED:
-  virtual std::string get_ir() const;
-  virtual Shader::ShaderType get_shader_type() const;
+  typedef pvector<Filename> Filenames;
+  Filenames _included_files;
+
+  friend class Shader;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    ShaderModule::init_type();
+    register_type(_type_handle, "ShaderModuleGlsl",
+                  ShaderModule::get_class_type());
+  }
+  virtual TypeHandle get_type() const override {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() override {
+    init_type();
+    return get_class_type();
+  }
+
+private:
+  static TypeHandle _type_handle;
 };
 };
+
 #endif
 #endif

+ 3 - 4
tests/shaderpipeline/test_shadercompiler.py

@@ -1,10 +1,9 @@
 from panda3d import core
 from panda3d import core
 
 
-GLSL_VERT_SHADER = """
-"""
+GLSL_VERT_SHADER = ""
 
 
 def test_shadercompiler_glsl(registry):
 def test_shadercompiler_glsl(registry):
     compiler = registry.get_compiler_from_language(core.Shader.SL_GLSL)
     compiler = registry.get_compiler_from_language(core.Shader.SL_GLSL)
-    module = compiler.compile_now(core.Shader.ST_vertex, GLSL_VERT_SHADER)
-    assert module.get_shader_type() == core.Shader.ST_vertex
+    module = compiler.compile_now(core.ShaderModule.Stage.vertex, core.StringStream(GLSL_VERT_SHADER.encode('utf-8')))
+    assert module.stage == core.ShaderModule.Stage.vertex
     assert module.get_ir() == GLSL_VERT_SHADER
     assert module.get_ir() == GLSL_VERT_SHADER