Browse Source

Use DSA for UBOs if available

rdb 10 years ago
parent
commit
80321bc2e2

+ 9 - 3
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1943,8 +1943,14 @@ reset() {
   if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) {
   if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) {
     _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)
     _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)
       get_extension_func("glGenerateTextureMipmap");
       get_extension_func("glGenerateTextureMipmap");
+    _glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)
+      get_extension_func("glMapNamedBufferRange");
+    _glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)
+      get_extension_func("glUnmapNamedBuffer");
+
+    _supports_dsa = true;
   } else {
   } else {
-    _glGenerateTextureMipmap = NULL;
+    _supports_dsa = false;
   }
   }
 #endif
 #endif
 
 
@@ -5225,7 +5231,7 @@ get_uniform_buffer(const GeomVertexArrayFormat *layout) {
   // Create a new uniform buffer.
   // Create a new uniform buffer.
   PT(CLP(UniformBufferContext)) ubc = new CLP(UniformBufferContext)(this, layout);
   PT(CLP(UniformBufferContext)) ubc = new CLP(UniformBufferContext)(this, layout);
   _glGenBuffers(1, &ubc->_index);
   _glGenBuffers(1, &ubc->_index);
-  GLsizeiptr size = layout->get_pad_to();
+  GLsizeiptr size = layout->get_stride();
 
 
   if (GLCAT.is_debug()) {
   if (GLCAT.is_debug()) {
     GLCAT.debug() << "creating new uniform buffer " << ubc->_index
     GLCAT.debug() << "creating new uniform buffer " << ubc->_index
@@ -12142,7 +12148,7 @@ upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
 void CLP(GraphicsStateGuardian)::
 void CLP(GraphicsStateGuardian)::
 generate_mipmaps(CLP(TextureContext) *gtc) {
 generate_mipmaps(CLP(TextureContext) *gtc) {
 #ifndef OPENGLES
 #ifndef OPENGLES
-  if (_glGenerateTextureMipmap != NULL) {
+  if (_supports_dsa) {
     // OpenGL 4.5 offers an easy way to do this without binding.
     // OpenGL 4.5 offers an easy way to do this without binding.
     _glGenerateTextureMipmap(gtc->_index);
     _glGenerateTextureMipmap(gtc->_index);
     return;
     return;

+ 3 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -834,7 +834,10 @@ public:
   PFNGLBINDPROGRAMARBPROC _glBindProgram;
   PFNGLBINDPROGRAMARBPROC _glBindProgram;
 
 
 #ifndef OPENGLES
 #ifndef OPENGLES
+  bool _supports_dsa;
   PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap;
   PFNGLGENERATETEXTUREMIPMAPPROC _glGenerateTextureMipmap;
+  PFNGLMAPNAMEDBUFFERRANGEPROC _glMapNamedBufferRange;
+  PFNGLUNMAPNAMEDBUFFERPROC _glUnmapNamedBuffer;
 #endif
 #endif
 
 
   bool _supports_framebuffer_multisample;
   bool _supports_framebuffer_multisample;

+ 1 - 2
panda/src/glstuff/glShaderContext_src.cxx

@@ -527,7 +527,7 @@ reflect_uniform_block(int i, const char *name, char *name_buffer, GLsizei name_b
 
 
   // We use a GeomVertexArrayFormat to describe the uniform buffer layout.
   // We use a GeomVertexArrayFormat to describe the uniform buffer layout.
   GeomVertexArrayFormat *block_format = new GeomVertexArrayFormat;
   GeomVertexArrayFormat *block_format = new GeomVertexArrayFormat;
-  block_format->set_pad_to(data_size);
+  block_format->set_stride(data_size);
 
 
   // Get an array containing the indices of all the uniforms in this block.
   // Get an array containing the indices of all the uniforms in this block.
   GLuint *indices = (GLuint *)alloca(param_count * sizeof(GLint));
   GLuint *indices = (GLuint *)alloca(param_count * sizeof(GLint));
@@ -648,7 +648,6 @@ reflect_uniform_block(int i, const char *name, char *name_buffer, GLsizei name_b
                             num_components, numeric_type, contents,
                             num_components, numeric_type, contents,
                             offsets[ui], 4, param_size, astrides[ui]);
                             offsets[ui], 4, param_size, astrides[ui]);
     block_format->add_column(column);
     block_format->add_column(column);
-    cerr << ui << " = " << column << "\n";
   }
   }
 
 
   if (GLCAT.is_debug()) {
   if (GLCAT.is_debug()) {

+ 26 - 16
panda/src/glstuff/glUniformBufferContext_src.cxx

@@ -58,26 +58,32 @@ update_data(const ShaderAttrib *attrib) {
   //}
   //}
   _frame = ClockObject::get_global_clock()->get_frame_count();
   _frame = ClockObject::get_global_clock()->get_frame_count();
 
 
-  // Change the generic buffer binding target for the map operation.
-  if (_glgsg->_current_ubuffer_index != _index) {
-    _glgsg->_glBindBuffer(GL_UNIFORM_BUFFER, _index);
-    _glgsg->_current_ubuffer_index = _index;
-  }
-
   void *buffer;
   void *buffer;
-  GLsizeiptr size = _layout->get_pad_to();
+  GLsizeiptr size = _layout->get_stride();
 
 
-  if (_glgsg->_glMapBufferRange != NULL) {
-    // If we have glMapBufferRange, we can tell it we don't need the
-    // previous contents for future draw calls any more, preventing
-    // an unnecessary synchronization.
-    buffer = _glgsg->_glMapBufferRange(GL_UNIFORM_BUFFER, 0, size,
+  // Change the generic buffer binding target for the map operation.
+  if (_glgsg->_supports_dsa) {
+    buffer = _glgsg->_glMapNamedBufferRange(_index, 0, size,
       GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
       GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
 
 
   } else {
   } else {
-    // This old trick achieves more or less the same effect.
-    _glgsg->_glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STREAM_DRAW);
-    buffer = _glgsg->_glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
+    if (_glgsg->_current_ubuffer_index != _index) {
+      _glgsg->_glBindBuffer(GL_UNIFORM_BUFFER, _index);
+      _glgsg->_current_ubuffer_index = _index;
+    }
+
+    if (_glgsg->_glMapBufferRange != NULL) {
+      // If we have glMapBufferRange, we can tell it we don't need the
+      // previous contents for future draw calls any more, preventing
+      // an unnecessary synchronization.
+      buffer = _glgsg->_glMapBufferRange(GL_UNIFORM_BUFFER, 0, size,
+        GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+
+    } else {
+      // This old trick achieves more or less the same effect.
+      _glgsg->_glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_STREAM_DRAW);
+      buffer = _glgsg->_glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
+    }
   }
   }
 
 
   nassertv(buffer != NULL);
   nassertv(buffer != NULL);
@@ -122,7 +128,11 @@ update_data(const ShaderAttrib *attrib) {
     }
     }
   }
   }
 
 
-  _glgsg->_glUnmapBuffer(GL_UNIFORM_BUFFER);
+  if (_glgsg->_supports_dsa) {
+    _glgsg->_glUnmapNamedBuffer(_index);
+  } else {
+    _glgsg->_glUnmapBuffer(GL_UNIFORM_BUFFER);
+  }
 }
 }
 
 
 #endif
 #endif