2021-01-20 03:33:27 +00:00
|
|
|
using System;
|
2021-01-22 01:27:25 +00:00
|
|
|
using System.Runtime.InteropServices;
|
2021-01-20 03:33:27 +00:00
|
|
|
using RefreshCS;
|
|
|
|
|
|
|
|
namespace MoonWorks.Graphics
|
|
|
|
{
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Buffers are generic data containers that can be used by the GPU.
|
|
|
|
/// </summary>
|
2021-01-20 03:33:27 +00:00
|
|
|
public class Buffer : GraphicsResource
|
|
|
|
{
|
|
|
|
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyBuffer;
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Creates a buffer.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="device">An initialized GraphicsDevice.</param>
|
|
|
|
/// <param name="usageFlags">Specifies how the buffer will be used.</param>
|
|
|
|
/// <param name="sizeInBytes">The length of the array. Cannot be resized.</param>
|
2021-01-20 03:33:27 +00:00
|
|
|
public Buffer(
|
|
|
|
GraphicsDevice device,
|
2021-01-20 21:32:48 +00:00
|
|
|
BufferUsageFlags usageFlags,
|
2021-01-20 03:33:27 +00:00
|
|
|
uint sizeInBytes
|
|
|
|
) : base(device)
|
|
|
|
{
|
|
|
|
Handle = Refresh.Refresh_CreateBuffer(
|
|
|
|
device.Handle,
|
2021-01-20 21:32:48 +00:00
|
|
|
(Refresh.BufferUsageFlags) usageFlags,
|
2021-01-20 03:33:27 +00:00
|
|
|
sizeInBytes
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Asynchronously copies data into the buffer.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">An array of data to copy into the buffer.</param>
|
|
|
|
/// <param name="offsetInElements">Specifies where to start copying out of the array.</param>
|
|
|
|
/// <param name="lengthInElements">Specifies how many elements to copy.</param>
|
2021-01-20 03:33:27 +00:00
|
|
|
public unsafe void SetData<T>(
|
|
|
|
T[] data,
|
2021-02-02 06:53:24 +00:00
|
|
|
uint offsetInElements,
|
|
|
|
uint lengthInElements
|
2021-01-20 03:33:27 +00:00
|
|
|
) where T : unmanaged
|
|
|
|
{
|
2021-02-02 06:53:24 +00:00
|
|
|
var elementSize = Marshal.SizeOf<T>();
|
|
|
|
|
2021-01-20 03:33:27 +00:00
|
|
|
fixed (T* ptr = &data[0])
|
|
|
|
{
|
|
|
|
Refresh.Refresh_SetBufferData(
|
|
|
|
Device.Handle,
|
|
|
|
Handle,
|
2021-02-02 06:53:24 +00:00
|
|
|
(uint) (offsetInElements * elementSize),
|
2021-01-20 03:33:27 +00:00
|
|
|
(IntPtr) ptr,
|
2021-02-02 06:53:24 +00:00
|
|
|
(uint) (lengthInElements * elementSize)
|
2021-01-20 03:33:27 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Asynchronously copies data into the buffer.
|
|
|
|
/// This variant of this method copies the entire array.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">An array of data to copy.</param>
|
2021-01-22 01:27:25 +00:00
|
|
|
public unsafe void SetData<T>(
|
|
|
|
T[] data
|
|
|
|
) where T : unmanaged
|
|
|
|
{
|
|
|
|
fixed (T* ptr = &data[0])
|
|
|
|
{
|
|
|
|
Refresh.Refresh_SetBufferData(
|
|
|
|
Device.Handle,
|
|
|
|
Handle,
|
|
|
|
0,
|
|
|
|
(IntPtr)ptr,
|
|
|
|
(uint) (data.Length * Marshal.SizeOf<T>())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Asynchronously copies data into the buffer.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">A pointer to an array.</param>
|
|
|
|
/// <param name="offsetInBytes">Specifies where to start copying the data, in bytes.</param>
|
|
|
|
/// <param name="dataLengthInBytes">Specifies how many bytes of data to copy.</param>
|
2021-01-29 05:49:33 +00:00
|
|
|
public void SetData(
|
2021-01-26 02:18:25 +00:00
|
|
|
IntPtr data,
|
2021-01-29 05:49:33 +00:00
|
|
|
uint offsetInBytes,
|
2021-01-20 03:33:27 +00:00
|
|
|
uint dataLengthInBytes
|
2021-01-29 05:49:33 +00:00
|
|
|
) {
|
2021-01-20 03:33:27 +00:00
|
|
|
Refresh.Refresh_SetBufferData(
|
|
|
|
Device.Handle,
|
|
|
|
Handle,
|
|
|
|
offsetInBytes,
|
2021-01-26 02:18:25 +00:00
|
|
|
data,
|
2021-01-20 03:33:27 +00:00
|
|
|
dataLengthInBytes
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Asynchronously copies data into the buffer.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">A pointer to an array.</param>
|
|
|
|
/// <param name="offsetInBytes">Specifies where to start copying the data, in bytes.</param>
|
|
|
|
/// <param name="dataLengthInBytes">Specifies how many bytes of data to copy.</param>
|
2021-01-29 05:49:33 +00:00
|
|
|
public unsafe void SetData<T>(
|
|
|
|
T* data,
|
2021-02-02 06:53:24 +00:00
|
|
|
uint offsetInElements,
|
|
|
|
uint lengthInElements
|
2021-01-29 05:49:33 +00:00
|
|
|
) where T : unmanaged {
|
2021-02-02 06:53:24 +00:00
|
|
|
var elementSize = Marshal.SizeOf<T>();
|
2021-01-29 05:49:33 +00:00
|
|
|
Refresh.Refresh_SetBufferData(
|
|
|
|
Device.Handle,
|
|
|
|
Handle,
|
2021-02-02 06:53:24 +00:00
|
|
|
(uint) (offsetInElements * elementSize),
|
2021-01-29 05:49:33 +00:00
|
|
|
(IntPtr) data,
|
2021-02-02 06:53:24 +00:00
|
|
|
(uint) (lengthInElements * elementSize)
|
2021-01-29 05:49:33 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-24 20:43:35 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Reads data out of a buffer and into an array.
|
|
|
|
/// This operation is only guaranteed to read up-to-date data if GraphicsDevice.Wait is called first.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="data">The array that data will be copied to.</param>
|
|
|
|
/// <param name="dataLengthInBytes">The length of the data to read.</param>
|
2021-01-20 03:33:27 +00:00
|
|
|
public unsafe void GetData<T>(
|
|
|
|
T[] data,
|
|
|
|
uint dataLengthInBytes
|
|
|
|
) where T : unmanaged
|
|
|
|
{
|
|
|
|
fixed (T* ptr = &data[0])
|
|
|
|
{
|
|
|
|
Refresh.Refresh_GetBufferData(
|
|
|
|
Device.Handle,
|
|
|
|
Handle,
|
|
|
|
(IntPtr)ptr,
|
|
|
|
dataLengthInBytes
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|