Browse Source

glgsg: fix NV driver crash after deletion of buffer that is still bound to a generic attribute index not used by Cg shader after having been used by a GLSL shader directly prior if no shaders are used afterwards

rdb 6 years ago
parent
commit
8b0256e0f9

+ 12 - 8
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -131,6 +131,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
   // glVertexPointer).
   size_t nvarying = _shader->_var_spec.size();
   _attributes.resize(nvarying);
+  _used_generic_attribs.clear();
 
   for (size_t i = 0; i < nvarying; ++i) {
     const Shader::ShaderVarSpec &bind = _shader->_var_spec[i];
@@ -332,6 +333,9 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
 #endif
 
     _attributes[i] = loc;
+    if (loc >= 0) {
+      _used_generic_attribs.set_bit(loc);
+    }
   }
 
   _glgsg->report_my_gl_errors();
@@ -857,8 +861,6 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
     int start, stride, num_values;
     size_t nvarying = _shader->_var_spec.size();
 
-    GLuint max_p = 0;
-
     for (size_t i = 0; i < nvarying; ++i) {
       const Shader::ShaderVarSpec &bind = _shader->_var_spec[i];
       InternalName *name = bind._name;
@@ -893,8 +895,6 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
         // limited in the options we can set.
         GLenum type = _glgsg->get_numeric_type(numeric_type);
         if (p >= 0) {
-          max_p = std::max(max_p, (GLuint)p + 1);
-
           _glgsg->enable_vertex_attrib_array(p);
 
           if (numeric_type == GeomEnums::NT_packed_dabc) {
@@ -1018,10 +1018,14 @@ update_shader_vertex_arrays(ShaderContext *prev, bool force) {
       }
     }
 
-    // Disable attribute arrays we don't use.
-    GLint highest_p = _glgsg->_enabled_vertex_attrib_arrays.get_highest_on_bit() + 1;
-    for (GLint p = max_p; p < highest_p; ++p) {
-      _glgsg->disable_vertex_attrib_array(p);
+    // Disable enabled attribute arrays that we don't use.
+    BitMask32 disable = _glgsg->_enabled_vertex_attrib_arrays & ~_used_generic_attribs;
+    if (!disable.is_zero()) {
+      for (GLuint p = (GLuint)disable.get_lowest_on_bit(); p <= (GLuint)disable.get_highest_on_bit(); ++p) {
+        if (disable.get_bit(p)) {
+          _glgsg->disable_vertex_attrib_array(p);
+        }
+      }
     }
   }
 

+ 1 - 0
panda/src/glstuff/glCgShaderContext_src.h

@@ -68,6 +68,7 @@ private:
   GLuint _glsl_program;
 
   pvector<GLint> _attributes;
+  BitMask32 _used_generic_attribs;
   GLint _color_attrib_index;
   CGparameter _transform_table_param;
   CGparameter _slider_table_param;