Bladeren bron

Generic fixes and cleanup for geometry shaders and split shaders

rdb 16 jaren geleden
bovenliggende
commit
6c89228477

+ 3 - 3
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -358,7 +358,7 @@ rebuild_bitplanes() {
     int update;
     
     update = false;
-    for (int f = 0; f < 6; f++) {    
+    for (int f = 0; f < 6; f++) {
       if (_cubemap_fbo [f] == 0) {
         glgsg->_glGenFramebuffers(1, &_cubemap_fbo [f]);
         update = true;
@@ -369,7 +369,7 @@ rebuild_bitplanes() {
       }
     }
     
-    if (update) {    
+    if (update) {
       int color_attachment = GL_COLOR_ATTACHMENT0_EXT;
 
       for (int i=0; i<count_textures(); i++) {
@@ -413,7 +413,7 @@ rebuild_bitplanes() {
           case RTP_aux_float_1:
           case RTP_aux_float_2:
           case RTP_aux_float_3:
-            for (int f = 0; f < 6; f++) {    
+            for (int f = 0; f < 6; f++) {
               glgsg->bind_fbo(_cubemap_fbo [f]);
               glgsg->_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, color_attachment,
                                              GL_TEXTURE_CUBE_MAP_POSITIVE_X + f,

+ 4 - 11
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -834,36 +834,29 @@ reset() {
     if (basic_shaders_only) {
       _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
       _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
-      _shader_caps._active_gprofile = (int)0; // No geometry shader if only using basic
+      _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
     } else { 
       _shader_caps._active_vprofile = (int)cgGLGetLatestProfile(CG_GL_VERTEX);
       _shader_caps._active_fprofile = (int)cgGLGetLatestProfile(CG_GL_FRAGMENT);
-#ifdef CG_CL_GEOMETRY
       _shader_caps._active_gprofile = (int)cgGLGetLatestProfile(CG_GL_GEOMETRY);
-#else
-      _shader_caps._active_gprofile = (int)0;
-#endif
     }
     _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
     _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
-#ifdef CG_PROFILE_GPU_CP
     _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
-#else
-    _shader_caps._ultimate_gprofile = (int)0;
-#endif
+
     _glBindProgram = (PFNGLBINDPROGRAMARBPROC)
       get_extension_func(GLPREFIX_QUOTED, "BindProgramARB");
     // Bug workaround for radeons.
     // For some reason, OSX reports to have this extension too,
     // even when there's no ATI card, resulting in cgc not being
     // able to find the hint. So, I've disabled the hack there.
-#ifndef IS_OSX
+#ifndef __APPLE__
     if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
       if (has_extension("GL_ATI_draw_buffers")) {
         _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
       }
     }
-#endif // IS_OSX
+#endif // __APPLE__
   }
 #endif // HAVE_CG
 

+ 38 - 30
panda/src/glstuff/glShaderContext_src.cxx

@@ -57,39 +57,39 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
     
     // Load the program.
     
-    cgGLLoadProgram(_cg_vprogram);
-    CGerror verror = cgGetError();
-    if (verror != CG_NO_ERROR) {
-      const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB);
-      GLCAT.error() << "Could not load Cg vertex program:" << s->get_filename() << " (" << 
-        cgGetProfileString(cgGetProgramProfile(_cg_vprogram)) << " " << str << ")\n";
-      release_resources(gsg);
-    }
-    cgGLLoadProgram(_cg_fprogram);
-    CGerror ferror = cgGetError();
-    if (ferror != CG_NO_ERROR) {
-      const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB);
-      GLCAT.error() << "Could not load Cg fragment program:" << s->get_filename() << " (" << 
-        cgGetProfileString(cgGetProgramProfile(_cg_fprogram)) << " " << str << ")\n";
-      release_resources(gsg);
+    if (_cg_vprogram != 0) {
+      cgGLLoadProgram(_cg_vprogram);
+      CGerror verror = cgGetError();
+      if (verror != CG_NO_ERROR) {
+        const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB);
+        GLCAT.error() << "Could not load Cg vertex program:" << s->get_filename(Shader::ST_vertex) << " (" << 
+          cgGetProfileString(cgGetProgramProfile(_cg_vprogram)) << " " << str << ")\n";
+        release_resources(gsg);
+      }
     }
-    gsg->report_my_gl_errors();
-    if (_cg_gprogram != 0) {
-      cgGLLoadProgram(_cg_gprogram);
-      if (GLCAT.is_debug()) {
-        GLCAT.debug()
-          << "Loaded geom prog: " << _cg_gprogram << "\n";
+
+    if (_cg_fprogram != 0) {
+      cgGLLoadProgram(_cg_fprogram);
+      CGerror ferror = cgGetError();
+      if (ferror != CG_NO_ERROR) {
+        const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB);
+        GLCAT.error() << "Could not load Cg fragment program:" << s->get_filename(Shader::ST_fragment) << " (" << 
+          cgGetProfileString(cgGetProgramProfile(_cg_fprogram)) << " " << str << ")\n";
+        release_resources(gsg);
       }
+    }
 
+    if (_cg_gprogram != 0) {
+      cgGLLoadProgram(_cg_gprogram);
       CGerror gerror = cgGetError();
       if (gerror != CG_NO_ERROR) {
         const char *str = (const char *)GLP(GetString)(GL_PROGRAM_ERROR_STRING_ARB);
-        GLCAT.error() << "Could not load Cg geometry program:" << s->get_filename() << " (" << 
+        GLCAT.error() << "Could not load Cg geometry program:" << s->get_filename(Shader::ST_geometry) << " (" << 
           cgGetProfileString(cgGetProgramProfile(_cg_gprogram)) << " " << str << ")\n";
         release_resources(gsg);
       }
-      gsg->report_my_gl_errors();
     }
+    gsg->report_my_gl_errors();
   }
 #endif
 
@@ -416,10 +416,14 @@ bind(GSG *gsg, bool reissue_parameters) {
 #ifdef HAVE_CG
   if (_cg_context != 0) {
     // Bind the shaders.
-    cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram));
-    cgGLBindProgram(_cg_vprogram);
-    cgGLEnableProfile(cgGetProgramProfile(_cg_fprogram));
-    cgGLBindProgram(_cg_fprogram);
+    if (_cg_vprogram != 0) {
+      cgGLEnableProfile(cgGetProgramProfile(_cg_vprogram));
+      cgGLBindProgram(_cg_vprogram);
+    }
+    if (_cg_fprogram != 0) {
+      cgGLEnableProfile(cgGetProgramProfile(_cg_fprogram));
+      cgGLBindProgram(_cg_fprogram);
+    }
     if (_cg_gprogram != 0) {
       cgGLEnableProfile(cgGetProgramProfile(_cg_gprogram));
       cgGLBindProgram(_cg_gprogram);
@@ -443,8 +447,12 @@ unbind(GSG *gsg) {
 
 #ifdef HAVE_CG
   if (_cg_context != 0) {
-    cgGLDisableProfile(cgGetProgramProfile(_cg_vprogram));
-    cgGLDisableProfile(cgGetProgramProfile(_cg_fprogram));
+    if (_cg_vprogram != 0) {
+      cgGLDisableProfile(cgGetProgramProfile(_cg_vprogram));
+    }
+    if (_cg_fprogram != 0) {
+      cgGLDisableProfile(cgGetProgramProfile(_cg_fprogram));
+    }
     if (_cg_gprogram != 0) {
       cgGLDisableProfile(cgGetProgramProfile(_cg_gprogram));
     }
@@ -835,7 +843,7 @@ void CLP(ShaderContext)::
 cg_report_errors() {
   CGerror err = cgGetError();
   if (err != CG_NO_ERROR) {
-    GLCAT.error() << _shader->get_filename() << " " << cgGetErrorString(err) << "\n";
+    GLCAT.error() << cgGetErrorString(err) << "\n";
   }
 }
 #endif

+ 3 - 1
panda/src/gobj/shader.I

@@ -153,8 +153,10 @@ operator == (const ShaderCaps &other) const {
 #ifdef HAVE_CG
   if ((_active_vprofile != other._active_vprofile) ||
       (_active_fprofile != other._active_fprofile) ||
+      (_active_gprofile != other._active_gprofile) ||
       (_ultimate_vprofile != other._ultimate_vprofile) ||
-      (_ultimate_fprofile != other._ultimate_fprofile)) {
+      (_ultimate_fprofile != other._ultimate_fprofile) ||
+      (_ultimate_gprofile != other._ultimate_gprofile)) {
      return false;
   }
 #endif

+ 86 - 45
panda/src/gobj/shader.cxx

@@ -1229,17 +1229,30 @@ cg_compile_shader(const ShaderCaps &caps) {
 
   if (!_text->_separate || !_text->_vertex.empty()) {
     _cg_vprogram = cg_compile_entry_point("vshader", caps, ST_vertex);
+    if (_cg_vprogram == 0) {
+      cg_release_resources();
+      return false;
+    }
   }
 
   if (!_text->_separate || !_text->_fragment.empty()) {
     _cg_fprogram = cg_compile_entry_point("fshader", caps, ST_fragment);
+    if (_cg_fprogram == 0) {
+      cg_release_resources();
+      return false;
+    }
   }
 
   if ((_text->_separate && !_text->_geometry.empty()) || (!_text->_separate && _text->_shared.find("gshader") != -1)) {
     _cg_gprogram = cg_compile_entry_point("gshader", caps, ST_geometry);
+    if (_cg_gprogram == 0) {
+      cg_release_resources();
+      return false;
+    }
   }
 
-  if ((_cg_vprogram == 0)||(_cg_fprogram == 0)) {
+  if (_cg_vprogram == 0 && _cg_fprogram == 0 && _cg_gprogram == 0) {
+    gobj_cat.error() << "Shader must at least have one program!\n";
     cg_release_resources();
     return false;
   }
@@ -1253,7 +1266,7 @@ cg_compile_shader(const ShaderCaps &caps) {
 //  Description:
 ////////////////////////////////////////////////////////////////////
 bool Shader::
-cg_analyze_entry_point(CGprogram prog, ShaderType type /*bool fshader*/) {  // CG2 CHANGE
+cg_analyze_entry_point(CGprogram prog, ShaderType type) {
   CGparameter parameter;
   bool success = true;
   for (parameter = cgGetFirstLeafParameter(prog, CG_PROGRAM);
@@ -1265,7 +1278,7 @@ cg_analyze_entry_point(CGprogram prog, ShaderType type /*bool fshader*/) {  // C
       ShaderArgId id;
       id._name = cgGetParameterName(parameter);
 
-      id._type  = type;         // CG2 CHANGE
+      id._type  = type;
       id._seqno = -1;
       success &= compile_parameter(id,
                                    cg_parameter_type(parameter),
@@ -1317,10 +1330,12 @@ cg_analyze_shader(const ShaderCaps &caps) {
     return false;
   }
 
-  if (!cg_analyze_entry_point(_cg_fprogram, ST_fragment)) {
-    cg_release_resources();
-    clear_parameters();
-    return false;
+  if (_cg_fprogram != 0) {
+     if (!cg_analyze_entry_point(_cg_fprogram, ST_fragment)) {
+      cg_release_resources();
+      clear_parameters();
+      return false;
+    }
   }
 
   if (_var_spec.size() != 0) {
@@ -1330,10 +1345,12 @@ cg_analyze_shader(const ShaderCaps &caps) {
     return false;
   }
 
-  if (!cg_analyze_entry_point(_cg_vprogram, ST_vertex)) {
-    cg_release_resources();
-    clear_parameters();
-    return false;
+  if (_cg_vprogram != 0) {
+    if (!cg_analyze_entry_point(_cg_vprogram, ST_vertex)) {
+      cg_release_resources();
+      clear_parameters();
+      return false;
+    }
   }
 
   if (_cg_gprogram != 0) {
@@ -1362,16 +1379,16 @@ cg_analyze_shader(const ShaderCaps &caps) {
     const char *pixel_program;
     const char *geometry_program;
 
-    vertex_program   = cgGetProgramString (_cg_vprogram, CG_COMPILED_PROGRAM);
-    pixel_program    = cgGetProgramString (_cg_fprogram, CG_COMPILED_PROGRAM);
-    if (_cg_gprogram != 0) {
-      geometry_program = cgGetProgramString (_cg_gprogram, CG_COMPILED_PROGRAM);
+    if (_cg_vprogram != 0) {
+      vertex_program   = cgGetProgramString (_cg_vprogram, CG_COMPILED_PROGRAM);
+      gobj_cat.debug() << vertex_program << "\n";
+    }
+    if (_cg_fprogram != 0) {
+      pixel_program    = cgGetProgramString (_cg_fprogram, CG_COMPILED_PROGRAM);
+      gobj_cat.debug() << pixel_program << "\n";
     }
-
-    gobj_cat.debug() << vertex_program << "\n";
-    gobj_cat.debug() << pixel_program << "\n";
-
     if (_cg_gprogram != 0) {
+      geometry_program = cgGetProgramString (_cg_gprogram, CG_COMPILED_PROGRAM);
       gobj_cat.debug() << geometry_program << "\n";
     }
   }
@@ -1492,7 +1509,7 @@ cg_compile_for(const ShaderCaps &caps,
                CGcontext &ctx,
                CGprogram &vprogram,
                CGprogram &fprogram,
-               CGprogram &gprogram,     // CG2 CHANGE
+               CGprogram &gprogram,
                pvector<CGparameter> &map) {
 
   // Initialize the return values to empty.
@@ -1500,7 +1517,7 @@ cg_compile_for(const ShaderCaps &caps,
   ctx = 0;
   vprogram = 0;
   fprogram = 0;
-  gprogram = 0;   // CG2 CHANGE
+  gprogram = 0;
 
   map.clear();
 
@@ -1515,13 +1532,31 @@ cg_compile_for(const ShaderCaps &caps,
   // If the compile routine used the ultimate profile instead of the
   // active one, it means the active one isn't powerful enough to
   // compile the shader.
-  // This does not apply when a custom profile is set.
 
-  if ((_cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) ||
-      (_cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile)) {
-    gobj_cat.error() << "Cg program too complex for driver: "
-      << get_filename() << ". Try choosing a different profile.\n";
-    return false;
+  if (_filename->_separate) {
+    if (_cg_vprogram != 0 && _cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) {
+      gobj_cat.error() << "Cg vprogram too complex for driver: "
+        << get_filename(ST_vertex) << ". Try choosing a different profile.\n";
+      return false;
+    }
+    if (_cg_fprogram != 0 && _cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile) {
+      gobj_cat.error() << "Cg fprogram too complex for driver: "
+        << get_filename(ST_fragment) << ". Try choosing a different profile.\n";
+      return false;
+    }
+    if (_cg_gprogram != 0 && _cg_gprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_gprogram) != caps._active_gprofile) {
+      gobj_cat.error() << "Cg gprogram too complex for driver: "
+        << get_filename(ST_geometry) << ". Try choosing a different profile.\n";
+      return false;
+    }
+  } else {
+    if ((_cg_vprogram != 0 && _cg_vprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_vprogram) != caps._active_vprofile) ||
+        (_cg_fprogram != 0 && _cg_fprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_fprogram) != caps._active_fprofile) ||
+        (_cg_gprogram != 0 && _cg_gprofile == CG_PROFILE_UNKNOWN && cgGetProgramProfile(_cg_gprogram) != caps._active_gprofile)) {
+      gobj_cat.error() << "Cg program too complex for driver: "
+        << get_filename() << ". Try choosing a different profile.\n";
+      return false;
+    }
   }
 
   // Build a parameter map.
@@ -1561,12 +1596,12 @@ cg_compile_for(const ShaderCaps &caps,
   ctx = _cg_context;
   vprogram = _cg_vprogram;
   fprogram = _cg_fprogram;
-  gprogram = _cg_gprogram;  // CG2 CHANGE
+  gprogram = _cg_gprogram;
 
   _cg_context = 0;
   _cg_vprogram = 0;
   _cg_fprogram = 0;
-  _cg_gprogram = 0;     // CG2 CHANGE
+  _cg_gprogram = 0;
 
   _cg_last_caps.clear();
 
@@ -1594,11 +1629,11 @@ Shader(CPT(ShaderFile) filename, CPT(ShaderFile) text, const ShaderLanguage &lan
   _cg_context = 0;
   _cg_vprogram = 0;
   _cg_fprogram = 0;
-  _cg_gprogram = 0; // CG2 CHANGE
+  _cg_gprogram = 0;
   _cg_vprofile = CG_PROFILE_UNKNOWN;
   _cg_fprofile = CG_PROFILE_UNKNOWN;
   _cg_gprofile = CG_PROFILE_UNKNOWN;
-  if (_default_caps._ultimate_vprofile == 0) {
+  if (_default_caps._ultimate_vprofile == 0 || _default_caps._ultimate_vprofile == CG_PROFILE_UNKNOWN) {
     _default_caps._active_vprofile = CG_PROFILE_UNKNOWN;
     _default_caps._active_fprofile = CG_PROFILE_UNKNOWN;
     _default_caps._ultimate_vprofile = cgGetProfile("glslv");
@@ -1614,8 +1649,7 @@ Shader(CPT(ShaderFile) filename, CPT(ShaderFile) text, const ShaderLanguage &lan
     parse_line(header, true, true);
     if (header == "//Cg") {
       _language = SL_Cg;
-    }
-    if (header == "//GLSL") {
+    } else if (header == "//GLSL") {
       _language = SL_GLSL;
     }
   }
@@ -1680,7 +1714,6 @@ cg_get_profile_from_header(ShaderCaps& caps) {
       if ((int)buf.find("gp4vp") >= 0)
         caps._active_vprofile = cgGetProfile("gp4vp");
 
-      // older
       if ((int)buf.find("glslv") >= 0)
         caps._active_vprofile = cgGetProfile("glslv");
 
@@ -1708,11 +1741,13 @@ cg_get_profile_from_header(ShaderCaps& caps) {
       if ((int)buf.find("vs_3_0") >= 0)
         caps._active_vprofile = cgGetProfile("vs_3_0");
 
+      if ((int)buf.find("vs_4_0") >= 0)
+        caps._active_vprofile = cgGetProfile("vs_4_0");
+
       // Scan the line for known cg2 fragment program profiles
       if ((int)buf.find("gp4fp") >= 0)
         caps._active_fprofile = cgGetProfile("gp4fp");
 
-      // older
       if ((int)buf.find("glslf") >= 0)
         caps._active_fprofile = cgGetProfile("glslf");
 
@@ -1746,9 +1781,18 @@ cg_get_profile_from_header(ShaderCaps& caps) {
       if ((int)buf.find("ps_3_0") >= 0)
         caps._active_fprofile = cgGetProfile("ps_3_0");
 
+      if ((int)buf.find("ps_4_0") >= 0)
+        caps._active_fprofile = cgGetProfile("ps_4_0");
+
       // Scan the line for known cg2 geometry program profiles
       if ((int)buf.find("gp4gp") >= 0)
         caps._active_gprofile = cgGetProfile("gp4gp");
+
+      if ((int)buf.find("glslg") >= 0)
+        caps._active_gprofile = cgGetProfile("glslg");
+
+      if ((int)buf.find("gs_4_0") >= 0)
+        caps._active_gprofile = cgGetProfile("gs_4_0");
     }
   } while(_parse > lastParse);
 
@@ -2116,17 +2160,14 @@ release_all() {
 void Shader::ShaderCaps::
 clear() {
   _supports_glsl = false;
- 
+  
 #ifdef HAVE_CG
-  _active_vprofile = 0;
-  _active_fprofile = 0;
-  _ultimate_vprofile = 0;
-  _ultimate_fprofile = 0;
-
-  // BEGIN CG2 CHANGE
-  _active_gprofile = 0;
-  _ultimate_gprofile = 0;
-  // END CG2 CHANGE
+  _active_vprofile = CG_PROFILE_UNKNOWN;
+  _active_fprofile = CG_PROFILE_UNKNOWN;
+  _active_gprofile = CG_PROFILE_UNKNOWN;
+  _ultimate_vprofile = CG_PROFILE_UNKNOWN;
+  _ultimate_fprofile = CG_PROFILE_UNKNOWN;
+  _ultimate_gprofile = CG_PROFILE_UNKNOWN;
 #endif
 }