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:
@@ -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.
|
||||||
|
OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER,
|
||||||
|
new IntPtr(VertexSize * size),
|
||||||
|
IntPtr.Zero,
|
||||||
|
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
|
try
|
||||||
{
|
{
|
||||||
OpenGL.glBufferData(OpenGL.GL_ARRAY_BUFFER,
|
for (var offset = 0; offset < size; offset += zeroedArrayElementSize)
|
||||||
new IntPtr(VertexSize * size),
|
{
|
||||||
ptr.AddrOfPinnedObject(),
|
var length = Math.Min(zeroedArrayElementSize, size - offset);
|
||||||
OpenGL.GL_DYNAMIC_DRAW);
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user