Significantly reduce allocation of GCHandles, replace with inlined fixed statement in GL class.

This commit is contained in:
UnknownShadow200 2015-08-03 20:08:04 +10:00
parent dd2eb1105a
commit 281e815125
5 changed files with 52 additions and 31 deletions

View File

@ -307,10 +307,15 @@ namespace ClassicalSharp.GraphicsAPI {
batchStride = VertexPos3fTex2fCol4b.Size; batchStride = VertexPos3fTex2fCol4b.Size;
} }
public override void DrawIndexedVbBatch( DrawMode mode, int vb, int ib, int indicesCount, public override void BindVb( int vb ) {
int startVertex, int startIndex ) {
device.SetIndices( iBuffers[ib] );
device.SetStreamSource( 0, vBuffers[vb], 0, batchStride ); device.SetStreamSource( 0, vBuffers[vb], 0, batchStride );
}
public override void BindIb( int ib ) {
device.SetIndices( iBuffers[ib] );
}
public override void DrawIndexedVb( DrawMode mode, int indicesCount, int startVertex, int startIndex ) {
device.DrawIndexedPrimitives( modeMappings[(int)mode], startVertex, startVertex, device.DrawIndexedPrimitives( modeMappings[(int)mode], startVertex, startVertex,
indicesCount / 6 * 4, startIndex, NumPrimitives( indicesCount, mode ) ); indicesCount / 6 * 4, startIndex, NumPrimitives( indicesCount, mode ) );
} }

View File

@ -110,6 +110,8 @@ namespace ClassicalSharp.GraphicsAPI {
public abstract int InitIb( ushort[] indices, int indicesCount ); public abstract int InitIb( ushort[] indices, int indicesCount );
public abstract int InitIb( IntPtr indices, int indicesCount );
public abstract bool IsValidVb( int vb ); public abstract bool IsValidVb( int vb );
public abstract bool IsValidIb( int ib ); public abstract bool IsValidIb( int ib );

View File

@ -187,42 +187,44 @@ namespace ClassicalSharp.GraphicsAPI {
Action setupBatchFuncTex2f, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b; Action setupBatchFuncTex2f, setupBatchFuncCol4b, setupBatchFuncTex2fCol4b;
public unsafe override int CreateDynamicVb( VertexFormat format, int maxVertices ) { public unsafe override int CreateDynamicVb( VertexFormat format, int maxVertices ) {
int id = 0; int id = GenAndBind( BufferTarget.ArrayBuffer );
GL.GenBuffersARB( 1, &id );
int sizeInBytes = maxVertices * strideSizes[(int)format]; int sizeInBytes = maxVertices * strideSizes[(int)format];
GL.BindBufferARB( BufferTarget.ArrayBuffer, id );
GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, BufferUsageHint.DynamicDraw ); GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), IntPtr.Zero, BufferUsageHint.DynamicDraw );
return id; return id;
} }
public unsafe override int InitVb<T>( T[] vertices, VertexFormat format, int count ) { public unsafe override int InitVb<T>( T[] vertices, VertexFormat format, int count ) {
int id = 0; int id = GenAndBind( BufferTarget.ArrayBuffer );
GL.GenBuffersARB( 1, &id );
int sizeInBytes = count * strideSizes[(int)format]; int sizeInBytes = count * strideSizes[(int)format];
GL.BindBufferARB( BufferTarget.ArrayBuffer, id ); GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), vertices, BufferUsageHint.StaticDraw );
GCHandle handle = GCHandle.Alloc( vertices, GCHandleType.Pinned );
GL.BufferDataARB( BufferTarget.ArrayBuffer, new IntPtr( sizeInBytes ), handle.AddrOfPinnedObject(), BufferUsageHint.StaticDraw );
handle.Free();
return id; return id;
} }
public unsafe override int InitIb( ushort[] indices, int indicesCount ) { public unsafe override int InitIb( ushort[] indices, int indicesCount ) {
int id = GenAndBind( BufferTarget.ElementArrayBuffer );
int sizeInBytes = indicesCount * sizeof( ushort );
GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), indices, BufferUsageHint.StaticDraw );
return id;
}
public unsafe override int InitIb( IntPtr indices, int indicesCount ) {
int id = GenAndBind( BufferTarget.ElementArrayBuffer );
int sizeInBytes = indicesCount * sizeof( ushort );
GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), indices, BufferUsageHint.StaticDraw );
return id;
}
unsafe static int GenAndBind( BufferTarget target ) {
int id = 0; int id = 0;
GL.GenBuffersARB( 1, &id ); GL.GenBuffersARB( 1, &id );
int sizeInBytes = indicesCount * sizeof( ushort ); GL.BindBufferARB( target, id );
GL.BindBufferARB( BufferTarget.ElementArrayBuffer, id );
fixed( ushort* ptr = indices ) {
GL.BufferDataARB( BufferTarget.ElementArrayBuffer, new IntPtr( sizeInBytes ), (IntPtr)ptr, BufferUsageHint.StaticDraw );
}
return id; return id;
} }
public override void DrawDynamicVb<T>( DrawMode mode, int id, T[] vertices, VertexFormat format, int count ) { public override void DrawDynamicVb<T>( DrawMode mode, int id, T[] vertices, VertexFormat format, int count ) {
int sizeInBytes = count * strideSizes[(int)format]; int sizeInBytes = count * strideSizes[(int)format];
GL.BindBufferARB( BufferTarget.ArrayBuffer, id ); GL.BindBufferARB( BufferTarget.ArrayBuffer, id );
GCHandle handle = GCHandle.Alloc( vertices, GCHandleType.Pinned ); GL.BufferSubDataARB( BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr( sizeInBytes ), vertices );
GL.BufferSubDataARB( BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr( sizeInBytes ), handle.AddrOfPinnedObject() );
handle.Free();
BeginVbBatch( format ); BeginVbBatch( format );
setupBatchFunc(); setupBatchFunc();
@ -317,20 +319,21 @@ namespace ClassicalSharp.GraphicsAPI {
GL.BindBufferARB( BufferTarget.ElementArrayBuffer, 0 ); GL.BindBufferARB( BufferTarget.ElementArrayBuffer, 0 );
} }
IntPtr zero = new IntPtr( 0 ), twelve = new IntPtr( 12 ), sixteen = new IntPtr( 16 );
void SetupVbPos3fTex2f() { void SetupVbPos3fTex2f() {
GL.VertexPointer( 3, PointerType.Float, 20, new IntPtr( 0 ) ); GL.VertexPointer( 3, PointerType.Float, VertexPos3fTex2f.Size, zero );
GL.TexCoordPointer( 2, PointerType.Float, 20, new IntPtr( 12 ) ); GL.TexCoordPointer( 2, PointerType.Float, VertexPos3fTex2f.Size, twelve );
} }
void SetupVbPos3fCol4b() { void SetupVbPos3fCol4b() {
GL.VertexPointer( 3, PointerType.Float, 16, new IntPtr( 0 ) ); GL.VertexPointer( 3, PointerType.Float, VertexPos3fCol4b.Size, zero );
GL.ColorPointer( 4, PointerType.UnsignedByte, 16, new IntPtr( 12 ) ); GL.ColorPointer( 4, PointerType.UnsignedByte, VertexPos3fCol4b.Size, twelve );
} }
void SetupVbPos3fTex2fCol4b() { void SetupVbPos3fTex2fCol4b() {
GL.VertexPointer( 3, PointerType.Float, 24, new IntPtr( 0 ) ); GL.VertexPointer( 3, PointerType.Float, VertexPos3fTex2fCol4b.Size, zero );
GL.ColorPointer( 4, PointerType.UnsignedByte, 24, new IntPtr( 12 ) ); GL.ColorPointer( 4, PointerType.UnsignedByte, VertexPos3fTex2fCol4b.Size, twelve );
GL.TexCoordPointer( 2, PointerType.Float, 24, new IntPtr( 16 ) ); GL.TexCoordPointer( 2, PointerType.Float, VertexPos3fTex2fCol4b.Size, sixteen );
} }
#endregion #endregion

View File

@ -38,6 +38,11 @@ namespace OpenTK.Graphics.OpenGL {
Interop.Calli( (int)target, size, data, (int)usage, BufferDataARBAddress ); Interop.Calli( (int)target, size, data, (int)usage, BufferDataARBAddress );
} static IntPtr BufferDataARBAddress; } static IntPtr BufferDataARBAddress;
public static void BufferDataARB<T>( BufferTarget target, IntPtr size, T[] data, BufferUsageHint usage ) where T : struct {
IntPtr dataPtr = Interop.Fixed( ref data[0] );
Interop.Calli( (int)target, size, dataPtr, (int)usage, BufferDataARBAddress );
}
public static void BufferSubData( BufferTarget target, IntPtr offset, IntPtr size, IntPtr data ) { public static void BufferSubData( BufferTarget target, IntPtr offset, IntPtr size, IntPtr data ) {
Interop.Calli( (int)target, offset, size, data, BufferSubDataAddress ); Interop.Calli( (int)target, offset, size, data, BufferSubDataAddress );
} static IntPtr BufferSubDataAddress; } static IntPtr BufferSubDataAddress;
@ -46,6 +51,11 @@ namespace OpenTK.Graphics.OpenGL {
Interop.Calli( (int)target, offset, size, data, BufferSubDataARBAddress ); Interop.Calli( (int)target, offset, size, data, BufferSubDataARBAddress );
} static IntPtr BufferSubDataARBAddress; } static IntPtr BufferSubDataARBAddress;
public static void BufferSubDataARB<T>( BufferTarget target, IntPtr offset, IntPtr size, T[] data ) where T : struct {
IntPtr dataPtr = Interop.Fixed( ref data[0] );
Interop.Calli( (int)target, offset, size, dataPtr, BufferSubDataARBAddress );
}
public static void Clear( ClearBufferMask mask ) { public static void Clear( ClearBufferMask mask ) {
Interop.Calli( (int)mask, ClearAddress ); Interop.Calli( (int)mask, ClearAddress );
} static IntPtr ClearAddress; } static IntPtr ClearAddress;

View File

@ -5,6 +5,7 @@ namespace OpenTK.Graphics.OpenGL {
internal static unsafe class Interop { internal static unsafe class Interop {
static Exception rewriteEx = new NotImplementedException( "You need to run InteropPatcher on this dll." ); static Exception rewriteEx = new NotImplementedException( "You need to run InteropPatcher on this dll." );
public static IntPtr Fixed<T>( ref T data ) { throw rewriteEx; }
public static void Calli( IntPtr address ) { throw rewriteEx; } public static void Calli( IntPtr address ) { throw rewriteEx; }
public static int Calli_Int32( IntPtr address ) { throw rewriteEx; } public static int Calli_Int32( IntPtr address ) { throw rewriteEx; }
public static void Calli( int arg0, IntPtr address ) { throw rewriteEx; } public static void Calli( int arg0, IntPtr address ) { throw rewriteEx; }