Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Cache whether or not a VBO is bound when using GL #2123

Closed
wants to merge 1 commit into from

5 participants

David Gow MonoGame Build Bot Steve 'Sly' Williams Ethan Lee Tom Spilman
David Gow

Reduces number of redundant glBindBuffer() calls when using DrawUser*Primitives several times in a row.

Basically, at the moment, every DrawUserPrimatives call (with the GL backend) starts by calling glBindBuffer() a couple of times to bind the null buffer as both a vertex and element (index) buffer. This patch basically caches whether or not the last draw operation was from a User pointer, and so the glBindBuffer calls only happen on the first DrawUserPrimatives call after a non-user-pointer call.

The actual performance improvement here is pretty small, but it sure makes digging through traces in apitrace more pleasent.

NB: It would be possible to cache whether or not vertex and index buffers are bound separately, but I doubt it's worth it.

— David

David Gow sulix Cache whether or not a VBO is bound when using GL
Reduces number of redundant glBindBuffer() calls when using
DrawUser*Primitives several times in a row.
054ef6a
MonoGame Build Bot
Collaborator

Can one of the admins verify this patch?

MonoGame Build Bot
Collaborator

Can one of the admins verify this patch?

Steve 'Sly' Williams
Owner
Ethan Lee

When I do the GL hardware instancing (this week, I hope) with #1767 I'll use these changes as well. Odds are I'll just bring this in along with the hardware instancing, and will be a pull request done after #1767 is merged.

Tom Spilman
Owner

Seems reasonable to me... less function calls is always a performance win.

Tom Spilman
Owner

I'm going to fix and resubmit this.

Tom Spilman tomspilman closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 10, 2013
  1. David Gow

    Cache whether or not a VBO is bound when using GL

    sulix authored
    Reduces number of redundant glBindBuffer() calls when using
    DrawUser*Primitives several times in a row.
This page is out of date. Refresh to see the latest.
Showing with 31 additions and 15 deletions.
  1. +31 −15 MonoGame.Framework/Graphics/GraphicsDevice.cs
46 MonoGame.Framework/Graphics/GraphicsDevice.cs
View
@@ -138,6 +138,7 @@ public class GraphicsDevice : IDisposable
private bool _pixelShaderDirty;
#if OPENGL
+ private bool _vertexBufferBound;
static List<Action> disposeActions = new List<Action>();
static object disposeActionsLock = new object();
#endif
@@ -535,6 +536,7 @@ internal void Initialize()
_vertexBufferDirty = true;
_vertexShaderDirty = true;
_pixelShaderDirty = true;
+ _vertexBufferBound = false;
// Set the default scissor rect.
_scissorRectangleDirty = true;
@@ -2075,6 +2077,7 @@ internal void ApplyState(bool applyShaders)
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.ibo);
GraphicsExtensions.CheckGLError();
+ _vertexBufferBound = true;
#endif
}
_indexBufferDirty = false;
@@ -2092,6 +2095,7 @@ internal void ApplyState(bool applyShaders)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, _vertexBuffer.vbo);
GraphicsExtensions.CheckGLError();
+ _vertexBufferBound = true;
}
#endif
}
@@ -2317,11 +2321,15 @@ public void DrawIndexedPrimitives(PrimitiveType primitiveType, int baseVertex, i
ApplyState(true);
// Unbind current VBOs.
- GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- _vertexBufferDirty = _indexBufferDirty = true;
+ if (_vertexBufferBound)
+ {
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ _vertexBufferDirty = _indexBufferDirty = true;
+ _vertexBufferBound = false;
+ }
// Pin the buffers.
var vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned);
@@ -2402,11 +2410,15 @@ public void DrawPrimitives(PrimitiveType primitiveType, int vertexStart, int pri
ApplyState(true);
// Unbind current VBOs.
- GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- _vertexBufferDirty = _indexBufferDirty = true;
+ if (_vertexBufferBound)
+ {
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ _vertexBufferDirty = _indexBufferDirty = true;
+ _vertexBufferBound = false;
+ }
// Pin the buffers.
var vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned);
@@ -2462,11 +2474,15 @@ public void DrawPrimitives(PrimitiveType primitiveType, int vertexStart, int pri
ApplyState(true);
// Unbind current VBOs.
- GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
- GraphicsExtensions.CheckGLError();
- _vertexBufferDirty = _indexBufferDirty = true;
+ if (_vertexBufferBound)
+ {
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
+ GraphicsExtensions.CheckGLError();
+ _vertexBufferDirty = _indexBufferDirty = true;
+ _vertexBufferBound = false;
+ }
// Pin the buffers.
var vbHandle = GCHandle.Alloc(vertexData, GCHandleType.Pinned);
Something went wrong with that request. Please try again.