mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 10:35:11 -04:00
Combine IndexBuffer and VertexBuffer, simplify methods of setting data, use inlined fixed instead of GCHandles.
This commit is contained in:
parent
cfeabc612a
commit
54afbcdb65
@ -21,8 +21,8 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
const int texBufferSize = 512, iBufferSize = 256, vBufferSize = 2048;
|
||||
|
||||
D3D.Texture[] textures = new D3D.Texture[texBufferSize];
|
||||
VertexBuffer[] vBuffers = new VertexBuffer[vBufferSize];
|
||||
IndexBuffer[] iBuffers = new IndexBuffer[iBufferSize];
|
||||
DataBuffer[] vBuffers = new DataBuffer[vBufferSize];
|
||||
DataBuffer[] iBuffers = new DataBuffer[iBufferSize];
|
||||
MatrixStack viewStack, projStack, texStack;
|
||||
MatrixStack curStack;
|
||||
PrimitiveType[] modeMappings = {
|
||||
@ -165,10 +165,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
|
||||
public override int CreateTexture( int width, int height, IntPtr scan0 ) {
|
||||
D3D.Texture texture = device.CreateTexture( width, height, 0, Usage.None, Format.A8R8G8B8, Pool.Managed );
|
||||
LockedRectangle vbData = texture.LockRectangle( 0, LockFlags.None );
|
||||
IntPtr dest = vbData.DataPointer;
|
||||
memcpy( scan0, dest, width * height * 4 );
|
||||
texture.UnlockRectangle( 0 );
|
||||
texture.SetData( scan0, width * height * 4, 0, LockFlags.None );
|
||||
return GetOrExpand( ref textures, texture, texBufferSize );
|
||||
}
|
||||
|
||||
@ -230,50 +227,33 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
};
|
||||
|
||||
public override int CreateVb<T>( T[] vertices, VertexFormat format, int count ) {
|
||||
GCHandle handle = GCHandle.Alloc( vertices, GCHandleType.Pinned );
|
||||
VertexBuffer buffer = CreateVertexBuffer( handle.AddrOfPinnedObject(), count, format );
|
||||
handle.Free();
|
||||
int size = count * strideSizes[(int)format];
|
||||
DataBuffer buffer = device.CreateVertexBuffer( size, Usage.None, formatMapping[(int)format], Pool.Managed );
|
||||
buffer.SetData( vertices, size, LockFlags.None );
|
||||
return GetOrExpand( ref vBuffers, buffer, vBufferSize );
|
||||
}
|
||||
|
||||
public override int CreateVb( IntPtr vertices, VertexFormat format, int count ) {
|
||||
VertexBuffer buffer = CreateVertexBuffer( vertices, count, format );
|
||||
int size = count * strideSizes[(int)format];
|
||||
DataBuffer buffer = device.CreateVertexBuffer( size, Usage.None, formatMapping[(int)format], Pool.Managed );
|
||||
buffer.SetData( vertices, size, LockFlags.None );
|
||||
return GetOrExpand( ref vBuffers, buffer, vBufferSize );
|
||||
}
|
||||
|
||||
public unsafe override int CreateIb( ushort[] indices, int indicesCount ) {
|
||||
IndexBuffer buffer;
|
||||
fixed( ushort* src = indices )
|
||||
buffer = CreateIndexBuffer( (IntPtr)src, indicesCount );
|
||||
|
||||
int size = indicesCount * sizeof( ushort );
|
||||
DataBuffer buffer = device.CreateIndexBuffer( size, Usage.None, Format.Index16, Pool.Managed );
|
||||
buffer.SetData( indices, size, LockFlags.None );
|
||||
return GetOrExpand( ref iBuffers, buffer, iBufferSize );
|
||||
}
|
||||
|
||||
public override int CreateIb( IntPtr indices, int indicesCount ) {
|
||||
IndexBuffer buffer = CreateIndexBuffer( indices, indicesCount );
|
||||
int size = indicesCount * sizeof( ushort );
|
||||
DataBuffer buffer = device.CreateIndexBuffer( size, Usage.None, Format.Index16, Pool.Managed );
|
||||
buffer.SetData( indices, size, LockFlags.None );
|
||||
return GetOrExpand( ref iBuffers, buffer, iBufferSize );
|
||||
}
|
||||
|
||||
unsafe VertexBuffer CreateVertexBuffer( IntPtr src, int count, VertexFormat format ) {
|
||||
int size = count * strideSizes[(int)format];
|
||||
VertexBuffer buffer = device.CreateVertexBuffer( size, Usage.None, formatMapping[(int)format], Pool.Managed );
|
||||
|
||||
IntPtr vbData = buffer.Lock( 0, size, LockFlags.None );
|
||||
memcpy( src, vbData, size );
|
||||
buffer.Unlock();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
unsafe IndexBuffer CreateIndexBuffer( IntPtr src, int count ) {
|
||||
int size = count * sizeof( ushort );
|
||||
IndexBuffer buffer = device.CreateIndexBuffer( size, Usage.None, Format.Index16, Pool.Managed );
|
||||
|
||||
IntPtr vbData = buffer.Lock( 0, size, LockFlags.None );
|
||||
memcpy( src, vbData, size );
|
||||
buffer.Unlock();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public override void DeleteVb( int vb ) {
|
||||
Delete( vBuffers, vb );
|
||||
}
|
||||
@ -474,29 +454,7 @@ namespace ClassicalSharp.GraphicsAPI {
|
||||
args.Windowed = true;
|
||||
return args;
|
||||
}
|
||||
|
||||
unsafe void memcpy( IntPtr srcPtr, IntPtr dstPtr, int bytes ) {
|
||||
byte* srcByte, dstByte;
|
||||
if( memcpy64Bit ) {
|
||||
long* srcLong = (long*)srcPtr, dstLong = (long*)dstPtr;
|
||||
while( bytes >= 8 ) {
|
||||
*dstLong++ = *srcLong++;
|
||||
bytes -= 8;
|
||||
}
|
||||
srcByte = (byte*)srcLong; dstByte = (byte*)dstLong;
|
||||
} else {
|
||||
int* srcInt = (int*)srcPtr, dstInt = (int*)dstPtr;
|
||||
while( bytes >= 4 ) {
|
||||
*dstInt++ = *srcInt++;
|
||||
bytes -= 4;
|
||||
}
|
||||
srcByte = (byte*)srcInt; dstByte = (byte*)dstInt;
|
||||
}
|
||||
for( int i = 0; i < bytes; i++ ) {
|
||||
*dstByte++ = *srcByte++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int GetOrExpand<T>( ref T[] array, T value, int expSize ) {
|
||||
// Find first free slot
|
||||
for( int i = 1; i < array.Length; i++ ) {
|
||||
|
@ -80,18 +80,18 @@ namespace SharpDX.Direct3D9
|
||||
return new Texture( pOut );
|
||||
}
|
||||
|
||||
public VertexBuffer CreateVertexBuffer(int length, Usage usage, VertexFormat vertexFormat, Pool pool) {
|
||||
public DataBuffer CreateVertexBuffer(int length, Usage usage, VertexFormat vertexFormat, Pool pool) {
|
||||
IntPtr pOut = IntPtr.Zero;
|
||||
int res = Interop.Calli(comPointer, length, (int)usage, (int)vertexFormat, (int)pool, (IntPtr)(void*)&pOut, IntPtr.Zero,(*(IntPtr**)comPointer)[26]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
return new VertexBuffer( pOut );
|
||||
return new DataBuffer( pOut );
|
||||
}
|
||||
|
||||
public IndexBuffer CreateIndexBuffer(int length, Usage usage, Format format, Pool pool) {
|
||||
public DataBuffer CreateIndexBuffer(int length, Usage usage, Format format, Pool pool) {
|
||||
IntPtr pOut = IntPtr.Zero;
|
||||
int res = Interop.Calli(comPointer, length, (int)usage, (int)format, (int)pool, (IntPtr)(void*)&pOut, IntPtr.Zero,(*(IntPtr**)comPointer)[27]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
return new IndexBuffer( pOut );
|
||||
return new DataBuffer( pOut );
|
||||
}
|
||||
|
||||
public void GetRenderTargetData(Surface renderTarget, Surface destSurface) {
|
||||
@ -189,12 +189,12 @@ namespace SharpDX.Direct3D9
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
}
|
||||
|
||||
public void SetStreamSource(int streamNumber, VertexBuffer streamData, int offsetInBytes, int stride) {
|
||||
public void SetStreamSource(int streamNumber, DataBuffer streamData, int offsetInBytes, int stride) {
|
||||
int res = Interop.Calli(comPointer, streamNumber,(streamData == null)?IntPtr.Zero:streamData.comPointer,offsetInBytes, stride,(*(IntPtr**)comPointer)[100]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
}
|
||||
|
||||
public void SetIndices(IndexBuffer indexData) {
|
||||
public void SetIndices(DataBuffer indexData) {
|
||||
int res = Interop.Calli(comPointer,(indexData == null)?IntPtr.Zero:indexData.comPointer,(*(IntPtr**)comPointer)[104]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace SharpDX.Direct3D9 {
|
||||
Adapters = new List<AdapterInformation>( count );
|
||||
for( int i = 0; i < count; i++ )
|
||||
Adapters.Add( new AdapterInformation( this, i ) );
|
||||
memcpy64Bit = IntPtr.Size == 8;
|
||||
}
|
||||
|
||||
public List<AdapterInformation> Adapters;
|
||||
@ -103,5 +104,29 @@ namespace SharpDX.Direct3D9 {
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
return new Device( devicePtr );
|
||||
}
|
||||
|
||||
// TODO: Place this in a utilities class.
|
||||
static bool memcpy64Bit;
|
||||
internal static unsafe void memcpy( IntPtr srcPtr, IntPtr dstPtr, int bytes ) {
|
||||
byte* srcByte, dstByte;
|
||||
if( memcpy64Bit ) {
|
||||
long* srcLong = (long*)srcPtr, dstLong = (long*)dstPtr;
|
||||
while( bytes >= 8 ) {
|
||||
*dstLong++ = *srcLong++;
|
||||
bytes -= 8;
|
||||
}
|
||||
srcByte = (byte*)srcLong; dstByte = (byte*)dstLong;
|
||||
} else {
|
||||
int* srcInt = (int*)srcPtr, dstInt = (int*)dstPtr;
|
||||
while( bytes >= 4 ) {
|
||||
*dstInt++ = *srcInt++;
|
||||
bytes -= 4;
|
||||
}
|
||||
srcByte = (byte*)srcInt; dstByte = (byte*)dstInt;
|
||||
}
|
||||
for( int i = 0; i < bytes; i++ ) {
|
||||
*dstByte++ = *srcByte++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ namespace SharpDX.Direct3D9 {
|
||||
}
|
||||
|
||||
[InteropPatch]
|
||||
public unsafe class IndexBuffer : Resource {
|
||||
public unsafe class DataBuffer : Resource { // Either 'VertexBuffer' or 'IndexBuffer
|
||||
|
||||
public IndexBuffer(IntPtr nativePtr) : base(nativePtr) {
|
||||
public DataBuffer(IntPtr nativePtr) : base(nativePtr) {
|
||||
}
|
||||
|
||||
public IntPtr Lock( int offsetToLock, int sizeToLock, LockFlags flags ) {
|
||||
@ -54,6 +54,19 @@ namespace SharpDX.Direct3D9 {
|
||||
return pOut;
|
||||
}
|
||||
|
||||
public void SetData( IntPtr data, int bytes, LockFlags flags ) {
|
||||
IntPtr dst = Lock( 0, bytes, flags );
|
||||
Direct3D.memcpy( data, dst, bytes );
|
||||
Unlock();
|
||||
}
|
||||
|
||||
public void SetData<T>( T[] data, int bytes, LockFlags flags ) where T : struct {
|
||||
IntPtr src = Interop.Fixed( ref data[0] );
|
||||
IntPtr dst = Lock( 0, bytes, flags );
|
||||
Direct3D.memcpy( src, dst, bytes );
|
||||
Unlock();
|
||||
}
|
||||
|
||||
public void Unlock() {
|
||||
int res = Interop.Calli(comPointer, (*(IntPtr**)comPointer)[12]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
@ -92,28 +105,15 @@ namespace SharpDX.Direct3D9 {
|
||||
return lockedRect;
|
||||
}
|
||||
|
||||
public void SetData( IntPtr data, int bytes, int level, LockFlags flags ) {
|
||||
LockedRectangle rect = LockRectangle( level, flags );
|
||||
Direct3D.memcpy( data, rect.DataPointer, bytes );
|
||||
UnlockRectangle( level );
|
||||
}
|
||||
|
||||
public void UnlockRectangle(int level) {
|
||||
int res = Interop.Calli(comPointer, level,(*(IntPtr**)comPointer)[20]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
}
|
||||
}
|
||||
|
||||
[InteropPatch]
|
||||
public unsafe class VertexBuffer : Resource {
|
||||
|
||||
public VertexBuffer(IntPtr nativePtr) : base(nativePtr) {
|
||||
}
|
||||
|
||||
public IntPtr Lock( int offsetToLock, int sizeToLock, LockFlags flags ) {
|
||||
IntPtr pOut;
|
||||
int res = Interop.Calli(comPointer, offsetToLock, sizeToLock, (IntPtr)(void*)&pOut, (int)flags, (*(IntPtr**)comPointer)[11]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
return pOut;
|
||||
}
|
||||
|
||||
public void Unlock() {
|
||||
int res = Interop.Calli(comPointer,(*(IntPtr**)comPointer)[12]);
|
||||
if( res < 0 ) { throw new SharpDXException( res ); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user