Don't allocate a full-sized array when creating a VertexBuffer.

We can allocate a much smaller zeroed buffer and copy that multiple times in order to zero the memory. When creating large VertexBuffers, this caps our temporary allocation size significantly.
This commit is contained in:
RoosterDragon
2017-11-20 20:11:29 +00:00
committed by abcdefg30
parent c269525397
commit 3f8c1ad5df

View File

@@ -27,20 +27,32 @@ namespace OpenRA.Platforms.Default
OpenGL.CheckGLError(); OpenGL.CheckGLError();
Bind(); Bind();
var ptr = GCHandle.Alloc(new T[size], GCHandleType.Pinned); // Generates a buffer with uninitialized memory.
try
{
OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER, OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER,
new IntPtr(VertexSize * size), new IntPtr(VertexSize * size),
ptr.AddrOfPinnedObject(), IntPtr.Zero,
OpenGL.GL_DYNAMIC_DRAW); OpenGL.GL_DYNAMIC_DRAW);
OpenGL.CheckGLError();
// We need to zero all the memory. Let's generate a smallish array and copy that over the whole buffer.
var zeroedArrayElementSize = Math.Min(size, 2048);
var ptr = GCHandle.Alloc(new T[zeroedArrayElementSize], GCHandleType.Pinned);
try
{
for (var offset = 0; offset < size; offset += zeroedArrayElementSize)
{
var length = Math.Min(zeroedArrayElementSize, size - offset);
OpenGL.glBufferSubData(OpenGL.GL_ARRAY_BUFFER,
new IntPtr(VertexSize * offset),
new IntPtr(VertexSize * length),
ptr.AddrOfPinnedObject());
OpenGL.CheckGLError();
}
} }
finally finally
{ {
ptr.Free(); ptr.Free();
} }
OpenGL.CheckGLError();
} }
public void SetData(T[] data, int length) public void SetData(T[] data, int length)
@@ -108,6 +120,7 @@ namespace OpenRA.Platforms.Default
return; return;
disposed = true; disposed = true;
OpenGL.glDeleteBuffers(1, ref buffer); OpenGL.glDeleteBuffers(1, ref buffer);
OpenGL.CheckGLError();
} }
} }
} }