refactor CopyPass
parent
97dee2a170
commit
3cfb43438c
|
@ -48,12 +48,13 @@ namespace MoonWorks
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="windowCreateInfo">The parameters that will be used to create the MainWindow.</param>
|
/// <param name="windowCreateInfo">The parameters that will be used to create the MainWindow.</param>
|
||||||
/// <param name="frameLimiterSettings">The frame limiter settings.</param>
|
/// <param name="frameLimiterSettings">The frame limiter settings.</param>
|
||||||
|
/// <param name="preferredBackends">Bitflags of which GPU backends to attempt to initialize.</param>
|
||||||
/// <param name="targetTimestep">How often Game.Update will run in terms of ticks per second.</param>
|
/// <param name="targetTimestep">How often Game.Update will run in terms of ticks per second.</param>
|
||||||
/// <param name="debugMode">If true, enables extra debug checks. Should be turned off for release builds.</param>
|
/// <param name="debugMode">If true, enables extra debug checks. Should be turned off for release builds.</param>
|
||||||
public Game(
|
public Game(
|
||||||
WindowCreateInfo windowCreateInfo,
|
WindowCreateInfo windowCreateInfo,
|
||||||
FrameLimiterSettings frameLimiterSettings,
|
FrameLimiterSettings frameLimiterSettings,
|
||||||
Span<Backend> preferredBackends,
|
BackendFlags preferredBackends,
|
||||||
int targetTimestep = 60,
|
int targetTimestep = 60,
|
||||||
bool debugMode = false
|
bool debugMode = false
|
||||||
) {
|
) {
|
||||||
|
@ -75,8 +76,6 @@ namespace MoonWorks
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Initialize();
|
|
||||||
|
|
||||||
Logger.LogInfo("Initializing input...");
|
Logger.LogInfo("Initializing input...");
|
||||||
Inputs = new Inputs();
|
Inputs = new Inputs();
|
||||||
|
|
||||||
|
@ -89,7 +88,7 @@ namespace MoonWorks
|
||||||
Logger.LogInfo("Initializing main window...");
|
Logger.LogInfo("Initializing main window...");
|
||||||
MainWindow = new Window(windowCreateInfo, GraphicsDevice.WindowFlags | SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN);
|
MainWindow = new Window(windowCreateInfo, GraphicsDevice.WindowFlags | SDL.SDL_WindowFlags.SDL_WINDOW_HIDDEN);
|
||||||
|
|
||||||
if (!GraphicsDevice.ClaimWindow(MainWindow, windowCreateInfo.PresentMode))
|
if (!GraphicsDevice.ClaimWindow(MainWindow, windowCreateInfo.SwapchainComposition, windowCreateInfo.PresentMode))
|
||||||
{
|
{
|
||||||
throw new System.SystemException("Could not claim window!");
|
throw new System.SystemException("Could not claim window!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,6 +617,7 @@ public class CommandBuffer
|
||||||
renderPass.Handle
|
renderPass.Handle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
renderPass.SetHandle(nint.Zero);
|
||||||
Device.RenderPassPool.Return(renderPass);
|
Device.RenderPassPool.Return(renderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -730,6 +731,45 @@ public class CommandBuffer
|
||||||
return computePass;
|
return computePass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public unsafe ComputePass BeginComputePass(
|
||||||
|
Span<StorageTextureReadWriteBinding> readWriteTextureBindings,
|
||||||
|
Span<StorageBufferReadWriteBinding> readWriteBufferBindings
|
||||||
|
) {
|
||||||
|
#if DEBUG
|
||||||
|
AssertNotSubmitted();
|
||||||
|
AssertNotInPass("Cannot begin compute pass while in another pass!");
|
||||||
|
computePassActive = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
var sdlTextureBindings = NativeMemory.Alloc(
|
||||||
|
(nuint) (readWriteTextureBindings.Length * Marshal.SizeOf<StorageTextureReadWriteBinding>())
|
||||||
|
);
|
||||||
|
|
||||||
|
var sdlBufferBindings = NativeMemory.Alloc(
|
||||||
|
(nuint) (readWriteBufferBindings.Length * Marshal.SizeOf<StorageBufferReadWriteBinding>())
|
||||||
|
);
|
||||||
|
|
||||||
|
var computePassHandle = SDL_Gpu.SDL_GpuBeginComputePass(
|
||||||
|
Handle,
|
||||||
|
(SDL_Gpu.StorageTextureReadWriteBinding*) sdlTextureBindings,
|
||||||
|
(uint) readWriteTextureBindings.Length,
|
||||||
|
(SDL_Gpu.StorageBufferReadWriteBinding*) sdlBufferBindings,
|
||||||
|
(uint) readWriteBufferBindings.Length
|
||||||
|
);
|
||||||
|
|
||||||
|
var computePass = Device.ComputePassPool.Obtain();
|
||||||
|
computePass.SetHandle(computePassHandle);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
computePass.active = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NativeMemory.Free(sdlTextureBindings);
|
||||||
|
NativeMemory.Free(sdlBufferBindings);
|
||||||
|
|
||||||
|
return computePass;
|
||||||
|
}
|
||||||
|
|
||||||
public void EndComputePass(ComputePass computePass)
|
public void EndComputePass(ComputePass computePass)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -742,6 +782,9 @@ public class CommandBuffer
|
||||||
SDL_Gpu.SDL_GpuEndComputePass(
|
SDL_Gpu.SDL_GpuEndComputePass(
|
||||||
computePass.Handle
|
computePass.Handle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
computePass.SetHandle(nint.Zero);
|
||||||
|
Device.ComputePassPool.Return(computePass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy Pass
|
// Copy Pass
|
||||||
|
@ -751,7 +794,7 @@ public class CommandBuffer
|
||||||
/// All copy commands must be made within a copy pass.
|
/// All copy commands must be made within a copy pass.
|
||||||
/// It is an error to call this during any kind of pass.
|
/// It is an error to call this during any kind of pass.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void BeginCopyPass()
|
public CopyPass BeginCopyPass()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
AssertNotSubmitted();
|
AssertNotSubmitted();
|
||||||
|
@ -759,228 +802,15 @@ public class CommandBuffer
|
||||||
copyPassActive = true;
|
copyPassActive = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Refresh.Refresh_BeginCopyPass(
|
var copyPassHandle = SDL_Gpu.SDL_GpuBeginCopyPass(Handle);
|
||||||
Device.Handle,
|
|
||||||
Handle
|
var copyPass = Device.CopyPassPool.Obtain();
|
||||||
);
|
copyPass.SetHandle(copyPassHandle);
|
||||||
|
|
||||||
|
return copyPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EndCopyPass(CopyPass copyPass)
|
||||||
/// <summary>
|
|
||||||
/// Uploads data from a TransferBuffer to a TextureSlice.
|
|
||||||
/// This copy occurs on the GPU timeline.
|
|
||||||
///
|
|
||||||
/// Overwriting the contents of the TransferBuffer before the command buffer
|
|
||||||
/// has finished execution will cause undefined behavior.
|
|
||||||
///
|
|
||||||
/// You MAY assume that the copy has finished for subsequent commands.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="writeOption">Specifies data dependency behavior.</param>
|
|
||||||
public void UploadToTexture(
|
|
||||||
TransferBuffer transferBuffer,
|
|
||||||
in TextureRegion textureRegion,
|
|
||||||
in BufferImageCopy copyParams,
|
|
||||||
WriteOptions writeOption
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
AssertNotSubmitted();
|
|
||||||
AssertInCopyPass("Cannot upload to texture outside of copy pass!");
|
|
||||||
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Refresh.Refresh_UploadToTexture(
|
|
||||||
Device.Handle,
|
|
||||||
Handle,
|
|
||||||
transferBuffer.Handle,
|
|
||||||
textureRegion.ToRefreshTextureRegion(),
|
|
||||||
copyParams.ToRefresh(),
|
|
||||||
(Refresh.WriteOptions) writeOption
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uploads the contents of an entire buffer to a texture with no mips.
|
|
||||||
/// </summary>
|
|
||||||
public void UploadToTexture(
|
|
||||||
TransferBuffer transferBuffer,
|
|
||||||
Texture texture,
|
|
||||||
WriteOptions writeOption
|
|
||||||
) {
|
|
||||||
UploadToTexture(
|
|
||||||
transferBuffer,
|
|
||||||
new TextureRegion(texture),
|
|
||||||
new BufferImageCopy(0, 0, 0),
|
|
||||||
writeOption
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uploads data from a TransferBuffer to a GpuBuffer.
|
|
||||||
/// This copy occurs on the GPU timeline.
|
|
||||||
///
|
|
||||||
/// Overwriting the contents of the TransferBuffer before the command buffer
|
|
||||||
/// has finished execution will cause undefined behavior.
|
|
||||||
///
|
|
||||||
/// You MAY assume that the copy has finished for subsequent commands.
|
|
||||||
/// </summary>
|
|
||||||
public void UploadToBuffer(
|
|
||||||
TransferBuffer transferBuffer,
|
|
||||||
GpuBuffer gpuBuffer,
|
|
||||||
in BufferCopy copyParams,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
#if DEBUG
|
|
||||||
AssertNotSubmitted();
|
|
||||||
AssertInCopyPass("Cannot upload to texture outside of copy pass!");
|
|
||||||
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.SrcOffset, copyParams.Size);
|
|
||||||
AssertBufferBoundsCheck(gpuBuffer.Size, copyParams.DstOffset, copyParams.Size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Refresh.Refresh_UploadToBuffer(
|
|
||||||
Device.Handle,
|
|
||||||
Handle,
|
|
||||||
transferBuffer.Handle,
|
|
||||||
gpuBuffer.Handle,
|
|
||||||
copyParams.ToRefresh(),
|
|
||||||
(Refresh.WriteOptions) option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies the entire contents of a TransferBuffer to a GpuBuffer.
|
|
||||||
/// </summary>
|
|
||||||
public void UploadToBuffer(
|
|
||||||
TransferBuffer transferBuffer,
|
|
||||||
GpuBuffer gpuBuffer,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
UploadToBuffer(
|
|
||||||
transferBuffer,
|
|
||||||
gpuBuffer,
|
|
||||||
new BufferCopy(0, 0, transferBuffer.Size),
|
|
||||||
option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies data element-wise into from a TransferBuffer to a GpuBuffer.
|
|
||||||
/// </summary>
|
|
||||||
public void UploadToBuffer<T>(
|
|
||||||
TransferBuffer transferBuffer,
|
|
||||||
GpuBuffer gpuBuffer,
|
|
||||||
uint sourceStartElement,
|
|
||||||
uint destinationStartElement,
|
|
||||||
uint numElements,
|
|
||||||
WriteOptions option
|
|
||||||
) where T : unmanaged
|
|
||||||
{
|
|
||||||
var elementSize = Marshal.SizeOf<T>();
|
|
||||||
var dataLengthInBytes = (uint) (elementSize * numElements);
|
|
||||||
var srcOffsetInBytes = (uint) (elementSize * sourceStartElement);
|
|
||||||
var dstOffsetInBytes = (uint) (elementSize * destinationStartElement);
|
|
||||||
|
|
||||||
UploadToBuffer(
|
|
||||||
transferBuffer,
|
|
||||||
gpuBuffer,
|
|
||||||
new BufferCopy(
|
|
||||||
srcOffsetInBytes,
|
|
||||||
dstOffsetInBytes,
|
|
||||||
dataLengthInBytes
|
|
||||||
),
|
|
||||||
option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies the contents of a TextureSlice to another TextureSlice.
|
|
||||||
/// The slices must have the same dimensions.
|
|
||||||
/// This copy occurs on the GPU timeline.
|
|
||||||
///
|
|
||||||
/// You MAY assume that the copy has finished in subsequent commands.
|
|
||||||
/// </summary>
|
|
||||||
public void CopyTextureToTexture(
|
|
||||||
in TextureRegion source,
|
|
||||||
in TextureRegion destination,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
#if DEBUG
|
|
||||||
AssertNotSubmitted();
|
|
||||||
AssertInCopyPass("Cannot download from texture outside of copy pass!");
|
|
||||||
AssertTextureBoundsCheck(destination.Size, source.Size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Refresh.Refresh_CopyTextureToTexture(
|
|
||||||
Device.Handle,
|
|
||||||
Handle,
|
|
||||||
source.ToRefreshTextureRegion(),
|
|
||||||
destination.ToRefreshTextureRegion(),
|
|
||||||
(Refresh.WriteOptions) option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies the contents of an entire Texture with no mips to another Texture with no mips.
|
|
||||||
/// The textures must have the same dimensions.
|
|
||||||
/// </summary>
|
|
||||||
public void CopyTextureToTexture(
|
|
||||||
Texture source,
|
|
||||||
Texture destination,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
CopyTextureToTexture(
|
|
||||||
new TextureRegion(source),
|
|
||||||
new TextureRegion(destination),
|
|
||||||
option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies data from a GpuBuffer to another GpuBuffer.
|
|
||||||
/// This copy occurs on the GPU timeline.
|
|
||||||
///
|
|
||||||
/// You MAY assume that the copy has finished in subsequent commands.
|
|
||||||
/// </summary>
|
|
||||||
public void CopyBufferToBuffer(
|
|
||||||
GpuBuffer source,
|
|
||||||
GpuBuffer destination,
|
|
||||||
in BufferCopy copyParams,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
#if DEBUG
|
|
||||||
AssertNotSubmitted();
|
|
||||||
AssertInCopyPass("Cannot download from texture outside of copy pass!");
|
|
||||||
AssertBufferBoundsCheck(source.Size, copyParams.SrcOffset, copyParams.Size);
|
|
||||||
AssertBufferBoundsCheck(destination.Size, copyParams.DstOffset, copyParams.Size);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Refresh.Refresh_CopyBufferToBuffer(
|
|
||||||
Device.Handle,
|
|
||||||
Handle,
|
|
||||||
source.Handle,
|
|
||||||
destination.Handle,
|
|
||||||
copyParams.ToRefresh(),
|
|
||||||
(Refresh.WriteOptions) option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Copies the entire contents of a GpuBuffer to another GpuBuffer.
|
|
||||||
/// </summary>
|
|
||||||
public void CopyBufferToBuffer(
|
|
||||||
GpuBuffer source,
|
|
||||||
GpuBuffer destination,
|
|
||||||
WriteOptions option
|
|
||||||
) {
|
|
||||||
CopyBufferToBuffer(
|
|
||||||
source,
|
|
||||||
destination,
|
|
||||||
new BufferCopy(0, 0, source.Size),
|
|
||||||
option
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void EndCopyPass()
|
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
AssertNotSubmitted();
|
AssertNotSubmitted();
|
||||||
|
@ -988,10 +818,12 @@ public class CommandBuffer
|
||||||
copyPassActive = false;
|
copyPassActive = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Refresh.Refresh_EndCopyPass(
|
SDL_Gpu.SDL_GpuEndCopyPass(
|
||||||
Device.Handle,
|
copyPass.Handle
|
||||||
Handle
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
copyPass.SetHandle(nint.Zero);
|
||||||
|
Device.CopyPassPool.Return(copyPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -1011,22 +843,6 @@ public class CommandBuffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AssertComputeBufferCount(int count)
|
|
||||||
{
|
|
||||||
if (currentComputePipeline.ComputeShaderInfo.BufferBindingCount != count)
|
|
||||||
{
|
|
||||||
throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.BufferBindingCount} buffers, but received {count}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AssertComputeTextureCount(int count)
|
|
||||||
{
|
|
||||||
if (currentComputePipeline.ComputeShaderInfo.ImageBindingCount != count)
|
|
||||||
{
|
|
||||||
throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.ImageBindingCount} textures, but received {count}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AssertTextureNotNull(ColorAttachmentInfo colorAttachmentInfo)
|
private void AssertTextureNotNull(ColorAttachmentInfo colorAttachmentInfo)
|
||||||
{
|
{
|
||||||
if (colorAttachmentInfo.TextureSlice.Texture == null || colorAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
|
if (colorAttachmentInfo.TextureSlice.Texture == null || colorAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
|
||||||
|
@ -1059,7 +875,7 @@ public class CommandBuffer
|
||||||
throw new System.ArgumentException("Render pass depth stencil attachment Texture cannot be null!");
|
throw new System.ArgumentException("Render pass depth stencil attachment Texture cannot be null!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((depthStencilAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.DepthStencilTarget) == 0)
|
if ((depthStencilAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.DepthStencil) == 0)
|
||||||
{
|
{
|
||||||
throw new System.ArgumentException("Render pass depth stencil attachment UsageFlags must include TextureUsageFlags.DepthStencilTarget!");
|
throw new System.ArgumentException("Render pass depth stencil attachment UsageFlags must include TextureUsageFlags.DepthStencilTarget!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using SDL2_gpuCS;
|
||||||
|
|
||||||
|
namespace MoonWorks.Graphics;
|
||||||
|
|
||||||
|
public class CopyPass
|
||||||
|
{
|
||||||
|
public nint Handle { get; private set; }
|
||||||
|
|
||||||
|
internal void SetHandle(nint handle)
|
||||||
|
{
|
||||||
|
Handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uploads data from a TransferBuffer to a TextureSlice.
|
||||||
|
/// This copy occurs on the GPU timeline.
|
||||||
|
///
|
||||||
|
/// Overwriting the contents of the TransferBuffer before the command buffer
|
||||||
|
/// has finished execution will cause undefined behavior.
|
||||||
|
///
|
||||||
|
/// You MAY assume that the copy has finished for subsequent commands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cycle">If true, cycles the texture if the given slice is bound.</param>
|
||||||
|
public void UploadToTexture(
|
||||||
|
TransferBuffer transferBuffer,
|
||||||
|
in TextureRegion textureRegion,
|
||||||
|
in BufferImageCopy copyParams,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
#if DEBUG
|
||||||
|
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Gpu.SDL_GpuUploadToTexture(
|
||||||
|
Handle,
|
||||||
|
transferBuffer.Handle,
|
||||||
|
textureRegion.ToSDL(),
|
||||||
|
copyParams.ToSDL(),
|
||||||
|
Conversions.BoolToInt(cycle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uploads the contents of an entire buffer to a 2D texture with no mips.
|
||||||
|
/// </summary>
|
||||||
|
public void UploadToTexture(
|
||||||
|
TransferBuffer transferBuffer,
|
||||||
|
Texture texture,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
UploadToTexture(
|
||||||
|
transferBuffer,
|
||||||
|
new TextureRegion(texture),
|
||||||
|
new BufferImageCopy(0, 0, 0),
|
||||||
|
cycle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uploads data from a TransferBuffer to a GpuBuffer.
|
||||||
|
/// This copy occurs on the GPU timeline.
|
||||||
|
///
|
||||||
|
/// Overwriting the contents of the TransferBuffer before the command buffer
|
||||||
|
/// has finished execution will cause undefined behavior.
|
||||||
|
///
|
||||||
|
/// You MAY assume that the copy has finished for subsequent commands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cycle">If true, cycles the buffer if it is bound.</param>
|
||||||
|
public void UploadToBuffer(
|
||||||
|
TransferBuffer transferBuffer,
|
||||||
|
GpuBuffer buffer,
|
||||||
|
in BufferCopy copyParams,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
#if DEBUG
|
||||||
|
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.SrcOffset, copyParams.Size);
|
||||||
|
AssertBufferBoundsCheck(buffer.Size, copyParams.DstOffset, copyParams.Size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Gpu.SDL_GpuUploadToBuffer(
|
||||||
|
Handle,
|
||||||
|
transferBuffer.Handle,
|
||||||
|
buffer.Handle,
|
||||||
|
copyParams.ToSDL(),
|
||||||
|
Conversions.BoolToInt(cycle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the entire contents of a TransferBuffer to a GpuBuffer.
|
||||||
|
/// </summary>
|
||||||
|
public void UploadToBuffer(
|
||||||
|
TransferBuffer transferBuffer,
|
||||||
|
GpuBuffer buffer,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
UploadToBuffer(
|
||||||
|
transferBuffer,
|
||||||
|
buffer,
|
||||||
|
new BufferCopy(0, 0, transferBuffer.Size),
|
||||||
|
cycle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies data element-wise into from a TransferBuffer to a GpuBuffer.
|
||||||
|
/// </summary>
|
||||||
|
public void UploadToBuffer<T>(
|
||||||
|
TransferBuffer transferBuffer,
|
||||||
|
GpuBuffer buffer,
|
||||||
|
uint sourceStartElement,
|
||||||
|
uint destinationStartElement,
|
||||||
|
uint numElements,
|
||||||
|
bool cycle
|
||||||
|
) where T : unmanaged
|
||||||
|
{
|
||||||
|
var elementSize = Marshal.SizeOf<T>();
|
||||||
|
var dataLengthInBytes = (uint) (elementSize * numElements);
|
||||||
|
var srcOffsetInBytes = (uint) (elementSize * sourceStartElement);
|
||||||
|
var dstOffsetInBytes = (uint) (elementSize * destinationStartElement);
|
||||||
|
|
||||||
|
UploadToBuffer(
|
||||||
|
transferBuffer,
|
||||||
|
buffer,
|
||||||
|
new BufferCopy(srcOffsetInBytes, dstOffsetInBytes, dataLengthInBytes),
|
||||||
|
cycle
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies the contents of a TextureRegion to another TextureRegion.
|
||||||
|
/// The regions must have the same dimensions.
|
||||||
|
/// This copy occurs on the GPU timeline.
|
||||||
|
///
|
||||||
|
/// You MAY assume that the copy has finished in subsequent commands.
|
||||||
|
/// </summary>
|
||||||
|
public void CopyTextureToTexture(
|
||||||
|
in TextureRegion source,
|
||||||
|
in TextureRegion destination,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
#if DEBUG
|
||||||
|
AssertTextureBoundsCheck(destination.Size, source.Size);
|
||||||
|
|
||||||
|
if (source.Width != destination.Width || source.Height != destination.Height || source.Depth != destination.Depth)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException("Texture copy must have the same dimensions!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Gpu.SDL_GpuCopyTextureToTexture(
|
||||||
|
Handle,
|
||||||
|
source.ToSDL(),
|
||||||
|
destination.ToSDL(),
|
||||||
|
Conversions.BoolToInt(cycle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Copies data from a GpuBuffer to another GpuBuffer.
|
||||||
|
/// This copy occurs on the GPU timeline.
|
||||||
|
///
|
||||||
|
/// You MAY assume that the copy has finished in subsequent commands.
|
||||||
|
/// </summary>
|
||||||
|
public void CopyBufferToBuffer(
|
||||||
|
GpuBuffer source,
|
||||||
|
GpuBuffer destination,
|
||||||
|
in BufferCopy copyParams,
|
||||||
|
bool cycle
|
||||||
|
) {
|
||||||
|
#if DEBUG
|
||||||
|
AssertBufferBoundsCheck(source.Size, copyParams.SrcOffset, copyParams.Size);
|
||||||
|
AssertBufferBoundsCheck(destination.Size, copyParams.DstOffset, copyParams.Size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SDL_Gpu.SDL_GpuCopyBufferToBuffer(
|
||||||
|
Handle,
|
||||||
|
source.Handle,
|
||||||
|
destination.Handle,
|
||||||
|
copyParams.ToSDL(),
|
||||||
|
Conversions.BoolToInt(cycle)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
private void AssertBufferBoundsCheck(uint bufferLengthInBytes, uint offsetInBytes, uint copyLengthInBytes)
|
||||||
|
{
|
||||||
|
if (copyLengthInBytes > bufferLengthInBytes + offsetInBytes)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException($"SetBufferData overflow! buffer length {bufferLengthInBytes}, offset {offsetInBytes}, copy length {copyLengthInBytes}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AssertTextureBoundsCheck(uint textureSizeInBytes, uint dataLengthInBytes)
|
||||||
|
{
|
||||||
|
if (dataLengthInBytes > textureSizeInBytes)
|
||||||
|
{
|
||||||
|
throw new System.InvalidOperationException($"SetTextureData overflow! texture size {textureSizeInBytes}, data size {dataLengthInBytes}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace MoonWorks.Graphics;
|
||||||
|
|
||||||
|
internal class CopyPassPool
|
||||||
|
{
|
||||||
|
private ConcurrentQueue<CopyPass> CopyPasses = new ConcurrentQueue<CopyPass>();
|
||||||
|
|
||||||
|
public CopyPass Obtain()
|
||||||
|
{
|
||||||
|
if (CopyPasses.TryDequeue(out var copyPass))
|
||||||
|
{
|
||||||
|
return copyPass;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new CopyPass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Return(CopyPass copyPass)
|
||||||
|
{
|
||||||
|
CopyPasses.Enqueue(copyPass);
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,7 @@ namespace MoonWorks.Graphics
|
||||||
private FencePool FencePool;
|
private FencePool FencePool;
|
||||||
internal RenderPassPool RenderPassPool;
|
internal RenderPassPool RenderPassPool;
|
||||||
internal ComputePassPool ComputePassPool;
|
internal ComputePassPool ComputePassPool;
|
||||||
|
internal CopyPassPool CopyPassPool;
|
||||||
|
|
||||||
internal unsafe GraphicsDevice(
|
internal unsafe GraphicsDevice(
|
||||||
BackendFlags preferredBackends,
|
BackendFlags preferredBackends,
|
||||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RefreshCS;
|
using RefreshCS;
|
||||||
|
using SDL2;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,8 +26,8 @@ namespace MoonWorks.Graphics
|
||||||
uint textureDataOffset = 0;
|
uint textureDataOffset = 0;
|
||||||
uint textureDataSize = 1024;
|
uint textureDataSize = 1024;
|
||||||
|
|
||||||
List<(GpuBuffer, BufferCopy, WriteOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, WriteOptions)>();
|
List<(GpuBuffer, BufferCopy, bool)> BufferUploads = new List<(GpuBuffer, BufferCopy, bool)>();
|
||||||
List<(TextureRegion, uint, WriteOptions)> TextureUploads = new List<(TextureRegion, uint, WriteOptions)>();
|
List<(TextureRegion, uint, bool)> TextureUploads = new List<(TextureRegion, uint, bool)>();
|
||||||
|
|
||||||
public ResourceUploader(GraphicsDevice device) : base(device)
|
public ResourceUploader(GraphicsDevice device) : base(device)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ namespace MoonWorks.Graphics
|
||||||
var lengthInBytes = (uint) (Marshal.SizeOf<T>() * data.Length);
|
var lengthInBytes = (uint) (Marshal.SizeOf<T>() * data.Length);
|
||||||
var gpuBuffer = new GpuBuffer(Device, usageFlags, lengthInBytes);
|
var gpuBuffer = new GpuBuffer(Device, usageFlags, lengthInBytes);
|
||||||
|
|
||||||
SetBufferData(gpuBuffer, 0, data, WriteOptions.Unsafe);
|
SetBufferData(gpuBuffer, 0, data, false);
|
||||||
|
|
||||||
return gpuBuffer;
|
return gpuBuffer;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ namespace MoonWorks.Graphics
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prepares upload of data into a GpuBuffer.
|
/// Prepares upload of data into a GpuBuffer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetBufferData<T>(GpuBuffer buffer, uint bufferOffsetInElements, Span<T> data, WriteOptions option) where T : unmanaged
|
public void SetBufferData<T>(GpuBuffer buffer, uint bufferOffsetInElements, Span<T> data, bool cycle) where T : unmanaged
|
||||||
{
|
{
|
||||||
uint elementSize = (uint) Marshal.SizeOf<T>();
|
uint elementSize = (uint) Marshal.SizeOf<T>();
|
||||||
uint offsetInBytes = elementSize * bufferOffsetInElements;
|
uint offsetInBytes = elementSize * bufferOffsetInElements;
|
||||||
|
@ -66,7 +66,7 @@ namespace MoonWorks.Graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCopyParams = new BufferCopy(resourceOffset, offsetInBytes, lengthInBytes);
|
var bufferCopyParams = new BufferCopy(resourceOffset, offsetInBytes, lengthInBytes);
|
||||||
BufferUploads.Add((buffer, bufferCopyParams, option));
|
BufferUploads.Add((buffer, bufferCopyParams, cycle));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
|
@ -74,7 +74,7 @@ namespace MoonWorks.Graphics
|
||||||
public Texture CreateTexture2D<T>(Span<T> pixelData, uint width, uint height) where T : unmanaged
|
public Texture CreateTexture2D<T>(Span<T> pixelData, uint width, uint height) where T : unmanaged
|
||||||
{
|
{
|
||||||
var texture = Texture.CreateTexture2D(Device, width, height, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
var texture = Texture.CreateTexture2D(Device, width, height, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
|
||||||
SetTextureData(texture, pixelData, WriteOptions.Unsafe);
|
SetTextureData(texture, pixelData, false);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace MoonWorks.Graphics
|
||||||
Depth = 1
|
Depth = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
SetTextureData(textureRegion, byteSpan, WriteOptions.Unsafe);
|
SetTextureData(textureRegion, byteSpan, false);
|
||||||
|
|
||||||
NativeMemory.Free(byteBuffer);
|
NativeMemory.Free(byteBuffer);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,7 @@ namespace MoonWorks.Graphics
|
||||||
var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes);
|
var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes);
|
||||||
var pixelSpan = new Span<byte>((void*) pixelData, (int) sizeInBytes);
|
var pixelSpan = new Span<byte>((void*) pixelData, (int) sizeInBytes);
|
||||||
|
|
||||||
SetTextureData(textureRegion, pixelSpan, WriteOptions.Unsafe);
|
SetTextureData(textureRegion, pixelSpan, false);
|
||||||
|
|
||||||
ImageUtils.FreePixelData(pixelData);
|
ImageUtils.FreePixelData(pixelData);
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ namespace MoonWorks.Graphics
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prepares upload of pixel data into a TextureSlice.
|
/// Prepares upload of pixel data into a TextureSlice.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetTextureData<T>(TextureRegion textureRegion, Span<T> data, WriteOptions option) where T : unmanaged
|
public void SetTextureData<T>(TextureRegion textureRegion, Span<T> data, bool cycle) where T : unmanaged
|
||||||
{
|
{
|
||||||
var elementSize = Marshal.SizeOf<T>();
|
var elementSize = Marshal.SizeOf<T>();
|
||||||
var dataLengthInBytes = (uint) (elementSize * data.Length);
|
var dataLengthInBytes = (uint) (elementSize * data.Length);
|
||||||
|
@ -222,7 +222,7 @@ namespace MoonWorks.Graphics
|
||||||
resourceOffset = CopyTextureData(dataPtr, dataLengthInBytes, Texture.BytesPerPixel(textureRegion.TextureSlice.Texture.Format));
|
resourceOffset = CopyTextureData(dataPtr, dataLengthInBytes, Texture.BytesPerPixel(textureRegion.TextureSlice.Texture.Format));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureUploads.Add((textureRegion, resourceOffset, option));
|
TextureUploads.Add((textureRegion, resourceOffset, cycle));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload
|
// Upload
|
||||||
|
@ -263,11 +263,11 @@ namespace MoonWorks.Graphics
|
||||||
if (BufferTransferBuffer == null || BufferTransferBuffer.Size < bufferDataSize)
|
if (BufferTransferBuffer == null || BufferTransferBuffer.Size < bufferDataSize)
|
||||||
{
|
{
|
||||||
BufferTransferBuffer?.Dispose();
|
BufferTransferBuffer?.Dispose();
|
||||||
BufferTransferBuffer = new TransferBuffer(Device, TransferUsage.Buffer, bufferDataSize);
|
BufferTransferBuffer = new TransferBuffer(Device, TransferUsage.Buffer, TransferBufferMapFlags.Write, bufferDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataSpan = new Span<byte>(bufferData, (int) bufferDataSize);
|
var dataSpan = new Span<byte>(bufferData, (int) bufferDataSize);
|
||||||
BufferTransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
|
BufferTransferBuffer.SetData(dataSpan, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,21 +276,21 @@ namespace MoonWorks.Graphics
|
||||||
if (TextureTransferBuffer == null || TextureTransferBuffer.Size < textureDataSize)
|
if (TextureTransferBuffer == null || TextureTransferBuffer.Size < textureDataSize)
|
||||||
{
|
{
|
||||||
TextureTransferBuffer?.Dispose();
|
TextureTransferBuffer?.Dispose();
|
||||||
TextureTransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, textureDataSize);
|
TextureTransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, TransferBufferMapFlags.Write, textureDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataSpan = new Span<byte>(textureData, (int) textureDataSize);
|
var dataSpan = new Span<byte>(textureData, (int) textureDataSize);
|
||||||
TextureTransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
|
TextureTransferBuffer.SetData(dataSpan, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordUploadCommands(CommandBuffer commandBuffer)
|
private void RecordUploadCommands(CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
commandBuffer.BeginCopyPass();
|
var copyPass = commandBuffer.BeginCopyPass();
|
||||||
|
|
||||||
foreach (var (gpuBuffer, bufferCopyParams, option) in BufferUploads)
|
foreach (var (gpuBuffer, bufferCopyParams, option) in BufferUploads)
|
||||||
{
|
{
|
||||||
commandBuffer.UploadToBuffer(
|
copyPass.UploadToBuffer(
|
||||||
BufferTransferBuffer,
|
BufferTransferBuffer,
|
||||||
gpuBuffer,
|
gpuBuffer,
|
||||||
bufferCopyParams,
|
bufferCopyParams,
|
||||||
|
@ -300,7 +300,7 @@ namespace MoonWorks.Graphics
|
||||||
|
|
||||||
foreach (var (textureRegion, offset, option) in TextureUploads)
|
foreach (var (textureRegion, offset, option) in TextureUploads)
|
||||||
{
|
{
|
||||||
commandBuffer.UploadToTexture(
|
copyPass.UploadToTexture(
|
||||||
TextureTransferBuffer,
|
TextureTransferBuffer,
|
||||||
textureRegion,
|
textureRegion,
|
||||||
new BufferImageCopy(
|
new BufferImageCopy(
|
||||||
|
@ -312,7 +312,7 @@ namespace MoonWorks.Graphics
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuffer.EndCopyPass();
|
commandBuffer.EndCopyPass(copyPass);
|
||||||
|
|
||||||
BufferUploads.Clear();
|
BufferUploads.Clear();
|
||||||
TextureUploads.Clear();
|
TextureUploads.Clear();
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
using System;
|
using System;
|
||||||
using RefreshCS;
|
using SDL2_gpuCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fences allow you to track the status of a submitted command buffer. <br/>
|
||||||
|
/// You should only acquire a Fence if you will need to track the command buffer. <br/>
|
||||||
|
/// You should make sure to call GraphicsDevice.ReleaseFence when done with a Fence to avoid memory growth. <br/>
|
||||||
|
/// The Fence object itself is basically just a wrapper for the Refresh_Fence. <br/>
|
||||||
|
/// The internal handle is replaced so that we can pool Fence objects to manage garbage.
|
||||||
|
/// </summary>
|
||||||
|
public class Fence : SDL_GpuResource
|
||||||
{
|
{
|
||||||
/// <summary>
|
protected override Action<nint, nint> ReleaseFunction => SDL_Gpu.SDL_GpuReleaseFence;
|
||||||
/// Fences allow you to track the status of a submitted command buffer. <br/>
|
|
||||||
/// You should only acquire a Fence if you will need to track the command buffer. <br/>
|
internal Fence(GraphicsDevice device) : base(device)
|
||||||
/// You should make sure to call GraphicsDevice.ReleaseFence when done with a Fence to avoid memory growth. <br/>
|
|
||||||
/// The Fence object itself is basically just a wrapper for the Refresh_Fence. <br/>
|
|
||||||
/// The internal handle is replaced so that we can pool Fence objects to manage garbage.
|
|
||||||
/// </summary>
|
|
||||||
public class Fence : SDL_GpuResource
|
|
||||||
{
|
{
|
||||||
protected override Action<nint, nint> ReleaseFunction => Refresh.Refresh_ReleaseFence;
|
}
|
||||||
|
|
||||||
internal Fence(GraphicsDevice device) : base(device)
|
internal void SetHandle(nint handle)
|
||||||
{
|
{
|
||||||
}
|
Handle = handle;
|
||||||
|
|
||||||
internal void SetHandle(nint handle)
|
|
||||||
{
|
|
||||||
Handle = handle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
using RefreshCS;
|
using SDL2_gpuCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A sampler specifies how a texture will be sampled in a shader.
|
||||||
|
/// </summary>
|
||||||
|
public class Sampler : SDL_GpuResource
|
||||||
{
|
{
|
||||||
/// <summary>
|
protected override Action<IntPtr, IntPtr> ReleaseFunction => SDL_Gpu.SDL_GpuReleaseSampler;
|
||||||
/// A sampler specifies how a texture will be sampled in a shader.
|
|
||||||
/// </summary>
|
|
||||||
public class Sampler : SDL_GpuResource
|
|
||||||
{
|
|
||||||
protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroySampler;
|
|
||||||
|
|
||||||
public Sampler(
|
public Sampler(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
in SamplerCreateInfo samplerCreateInfo
|
in SamplerCreateInfo samplerCreateInfo
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateSampler(
|
Handle = SDL_Gpu.SDL_GpuCreateSampler(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
samplerCreateInfo.ToRefreshSamplerStateCreateInfo()
|
samplerCreateInfo.ToSDL()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RefreshCS;
|
using SDL2_gpuCS;
|
||||||
|
|
||||||
namespace MoonWorks.Graphics
|
namespace MoonWorks.Graphics
|
||||||
{
|
{
|
||||||
public unsafe class TransferBuffer : SDL_GpuResource
|
public unsafe class TransferBuffer : SDL_GpuResource
|
||||||
{
|
{
|
||||||
protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyTransferBuffer;
|
protected override Action<IntPtr, IntPtr> ReleaseFunction => SDL_Gpu.SDL_GpuReleaseTransferBuffer;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Size in bytes.
|
/// Size in bytes.
|
||||||
|
@ -23,12 +23,14 @@ namespace MoonWorks.Graphics
|
||||||
public unsafe static TransferBuffer Create<T>(
|
public unsafe static TransferBuffer Create<T>(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
TransferUsage usage,
|
TransferUsage usage,
|
||||||
|
TransferBufferMapFlags mapFlags,
|
||||||
uint elementCount
|
uint elementCount
|
||||||
) where T : unmanaged
|
) where T : unmanaged
|
||||||
{
|
{
|
||||||
return new TransferBuffer(
|
return new TransferBuffer(
|
||||||
device,
|
device,
|
||||||
usage,
|
usage,
|
||||||
|
mapFlags,
|
||||||
(uint) Marshal.SizeOf<T>() * elementCount
|
(uint) Marshal.SizeOf<T>() * elementCount
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -42,12 +44,14 @@ namespace MoonWorks.Graphics
|
||||||
public TransferBuffer(
|
public TransferBuffer(
|
||||||
GraphicsDevice device,
|
GraphicsDevice device,
|
||||||
TransferUsage usage,
|
TransferUsage usage,
|
||||||
|
TransferBufferMapFlags mapFlags,
|
||||||
uint sizeInBytes
|
uint sizeInBytes
|
||||||
) : base(device)
|
) : base(device)
|
||||||
{
|
{
|
||||||
Handle = Refresh.Refresh_CreateTransferBuffer(
|
Handle = SDL_Gpu.SDL_GpuCreateTransferBuffer(
|
||||||
device.Handle,
|
device.Handle,
|
||||||
(Refresh.TransferUsage) usage,
|
(SDL_Gpu.TransferUsage) usage,
|
||||||
|
(SDL_Gpu.TransferBufferMapFlags) mapFlags,
|
||||||
sizeInBytes
|
sizeInBytes
|
||||||
);
|
);
|
||||||
Size = sizeInBytes;
|
Size = sizeInBytes;
|
||||||
|
@ -57,16 +61,16 @@ namespace MoonWorks.Graphics
|
||||||
/// Immediately copies data from a Span to the TransferBuffer.
|
/// Immediately copies data from a Span to the TransferBuffer.
|
||||||
/// Returns the length of the copy in bytes.
|
/// Returns the length of the copy in bytes.
|
||||||
///
|
///
|
||||||
/// If setDataOption is DISCARD and this TransferBuffer was used in an Upload command,
|
/// If cycle is set to true and this TransferBuffer was used in an Upload command,
|
||||||
/// that command will still use the correct data at the cost of increased memory usage.
|
/// that command will still use the corret data at the cost of increased memory usage.
|
||||||
///
|
///
|
||||||
/// If setDataOption is OVERWRITE and this TransferBuffer was used in an Upload command,
|
/// If cycle is set to false, the data will be overwritten immediately,
|
||||||
/// the data will be overwritten immediately, which could cause a data race.
|
/// which could cause a data race.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe uint SetData<T>(
|
public unsafe uint SetData<T>(
|
||||||
Span<T> data,
|
Span<T> data,
|
||||||
uint bufferOffsetInBytes,
|
uint bufferOffsetInBytes,
|
||||||
TransferOptions setDataOption
|
bool cycle
|
||||||
) where T : unmanaged
|
) where T : unmanaged
|
||||||
{
|
{
|
||||||
var elementSize = Marshal.SizeOf<T>();
|
var elementSize = Marshal.SizeOf<T>();
|
||||||
|
@ -78,17 +82,17 @@ namespace MoonWorks.Graphics
|
||||||
|
|
||||||
fixed (T* dataPtr = data)
|
fixed (T* dataPtr = data)
|
||||||
{
|
{
|
||||||
Refresh.Refresh_SetTransferData(
|
SDL_Gpu.SDL_GpuSetTransferData(
|
||||||
Device.Handle,
|
Device.Handle,
|
||||||
(nint) dataPtr,
|
(nint) dataPtr,
|
||||||
Handle,
|
Handle,
|
||||||
new Refresh.BufferCopy
|
new SDL_Gpu.BufferCopy
|
||||||
{
|
{
|
||||||
srcOffset = 0,
|
SourceOffset = 0,
|
||||||
dstOffset = bufferOffsetInBytes,
|
DestinationOffset = bufferOffsetInBytes,
|
||||||
size = dataLengthInBytes
|
Size = dataLengthInBytes
|
||||||
},
|
},
|
||||||
(Refresh.TransferOptions) setDataOption
|
Conversions.BoolToInt(cycle)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,18 +103,18 @@ namespace MoonWorks.Graphics
|
||||||
/// Immediately copies data from a Span to the TransferBuffer.
|
/// Immediately copies data from a Span to the TransferBuffer.
|
||||||
/// Returns the length of the copy in bytes.
|
/// Returns the length of the copy in bytes.
|
||||||
///
|
///
|
||||||
/// If setDataOption is DISCARD and this TransferBuffer was used in an Upload command,
|
/// If cycle is set to true and this TransferBuffer was used in an Upload command,
|
||||||
/// that command will still use the correct data at the cost of increased memory usage.
|
/// that command will still use the corret data at the cost of increased memory usage.
|
||||||
///
|
///
|
||||||
/// If setDataOption is OVERWRITE and this TransferBuffer was used in an Upload command,
|
/// If cycle is set to false, the data will be overwritten immediately,
|
||||||
/// the data will be overwritten immediately, which could cause a data race.
|
/// which could cause a data race.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe uint SetData<T>(
|
public unsafe uint SetData<T>(
|
||||||
Span<T> data,
|
Span<T> data,
|
||||||
TransferOptions setDataOption
|
bool cycle
|
||||||
) where T : unmanaged
|
) where T : unmanaged
|
||||||
{
|
{
|
||||||
return SetData(data, 0, setDataOption);
|
return SetData(data, 0, cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -130,15 +134,15 @@ namespace MoonWorks.Graphics
|
||||||
|
|
||||||
fixed (T* dataPtr = data)
|
fixed (T* dataPtr = data)
|
||||||
{
|
{
|
||||||
Refresh.Refresh_GetTransferData(
|
SDL_Gpu.SDL_GpuGetTransferData(
|
||||||
Device.Handle,
|
Device.Handle,
|
||||||
Handle,
|
Handle,
|
||||||
(nint) dataPtr,
|
(nint) dataPtr,
|
||||||
new Refresh.BufferCopy
|
new SDL_Gpu.BufferCopy
|
||||||
{
|
{
|
||||||
srcOffset = bufferOffsetInBytes,
|
SourceOffset = bufferOffsetInBytes,
|
||||||
dstOffset = 0,
|
DestinationOffset = 0,
|
||||||
size = dataLengthInBytes
|
Size = dataLengthInBytes
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -788,7 +788,7 @@ public struct BufferCopy
|
||||||
Size = size;
|
Size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SDL_Gpu.BufferCopy ToRefresh()
|
public SDL_Gpu.BufferCopy ToSDL()
|
||||||
{
|
{
|
||||||
return new SDL_Gpu.BufferCopy
|
return new SDL_Gpu.BufferCopy
|
||||||
{
|
{
|
||||||
|
@ -811,7 +811,7 @@ public readonly record struct BufferImageCopy(
|
||||||
uint BufferStride,
|
uint BufferStride,
|
||||||
uint BufferImageHeight
|
uint BufferImageHeight
|
||||||
) {
|
) {
|
||||||
public SDL_Gpu.BufferImageCopy ToRefresh()
|
public SDL_Gpu.BufferImageCopy ToSDL()
|
||||||
{
|
{
|
||||||
return new SDL_Gpu.BufferImageCopy
|
return new SDL_Gpu.BufferImageCopy
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using RefreshCS;
|
|
||||||
|
|
||||||
namespace MoonWorks
|
namespace MoonWorks
|
||||||
{
|
{
|
||||||
|
@ -9,19 +8,6 @@ namespace MoonWorks
|
||||||
public static Action<string> LogWarn = LogWarnDefault;
|
public static Action<string> LogWarn = LogWarnDefault;
|
||||||
public static Action<string> LogError = LogErrorDefault;
|
public static Action<string> LogError = LogErrorDefault;
|
||||||
|
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogInfoFunc = RefreshLogInfo;
|
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogWarnFunc = RefreshLogWarn;
|
|
||||||
private static RefreshCS.Refresh.Refresh_LogFunc LogErrorFunc = RefreshLogError;
|
|
||||||
|
|
||||||
internal static void Initialize()
|
|
||||||
{
|
|
||||||
Refresh.Refresh_HookLogFunctions(
|
|
||||||
LogInfoFunc,
|
|
||||||
LogWarnFunc,
|
|
||||||
LogErrorFunc
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LogInfoDefault(string str)
|
private static void LogInfoDefault(string str)
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
|
|
@ -22,9 +22,13 @@
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ScreenMode ScreenMode;
|
public ScreenMode ScreenMode;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// Specifies the swapchain composition. Use SDR unless you know what you're doing.
|
||||||
|
/// </summary>
|
||||||
|
public Graphics.SwapchainComposition SwapchainComposition;
|
||||||
|
/// <summary>
|
||||||
/// Specifies the presentation mode for the window. Roughly equivalent to V-Sync.
|
/// Specifies the presentation mode for the window. Roughly equivalent to V-Sync.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PresentMode PresentMode;
|
public Graphics.PresentMode PresentMode;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the window can be resized using the operating system's window dragging feature.
|
/// Whether the window can be resized using the operating system's window dragging feature.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -39,7 +43,7 @@
|
||||||
uint windowWidth,
|
uint windowWidth,
|
||||||
uint windowHeight,
|
uint windowHeight,
|
||||||
ScreenMode screenMode,
|
ScreenMode screenMode,
|
||||||
PresentMode presentMode,
|
Graphics.PresentMode presentMode,
|
||||||
bool systemResizable = false,
|
bool systemResizable = false,
|
||||||
bool startMaximized = false
|
bool startMaximized = false
|
||||||
) {
|
) {
|
||||||
|
|
Loading…
Reference in New Issue