diff --git a/src/Game.cs b/src/Game.cs
index 1876814..2a1bbbf 100644
--- a/src/Game.cs
+++ b/src/Game.cs
@@ -48,12 +48,13 @@ namespace MoonWorks
///
/// The parameters that will be used to create the MainWindow.
/// The frame limiter settings.
+ /// Bitflags of which GPU backends to attempt to initialize.
/// How often Game.Update will run in terms of ticks per second.
/// If true, enables extra debug checks. Should be turned off for release builds.
public Game(
WindowCreateInfo windowCreateInfo,
FrameLimiterSettings frameLimiterSettings,
- Span preferredBackends,
+ BackendFlags preferredBackends,
int targetTimestep = 60,
bool debugMode = false
) {
@@ -75,8 +76,6 @@ namespace MoonWorks
return;
}
- Logger.Initialize();
-
Logger.LogInfo("Initializing input...");
Inputs = new Inputs();
@@ -89,7 +88,7 @@ namespace MoonWorks
Logger.LogInfo("Initializing main window...");
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!");
}
diff --git a/src/Graphics/CommandBuffer.cs b/src/Graphics/CommandBuffer.cs
index 229abf2..faf187f 100644
--- a/src/Graphics/CommandBuffer.cs
+++ b/src/Graphics/CommandBuffer.cs
@@ -617,6 +617,7 @@ public class CommandBuffer
renderPass.Handle
);
+ renderPass.SetHandle(nint.Zero);
Device.RenderPassPool.Return(renderPass);
}
@@ -730,6 +731,45 @@ public class CommandBuffer
return computePass;
}
+ public unsafe ComputePass BeginComputePass(
+ Span readWriteTextureBindings,
+ Span 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())
+ );
+
+ var sdlBufferBindings = NativeMemory.Alloc(
+ (nuint) (readWriteBufferBindings.Length * Marshal.SizeOf())
+ );
+
+ 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)
{
#if DEBUG
@@ -742,6 +782,9 @@ public class CommandBuffer
SDL_Gpu.SDL_GpuEndComputePass(
computePass.Handle
);
+
+ computePass.SetHandle(nint.Zero);
+ Device.ComputePassPool.Return(computePass);
}
// Copy Pass
@@ -751,7 +794,7 @@ public class CommandBuffer
/// All copy commands must be made within a copy pass.
/// It is an error to call this during any kind of pass.
///
- public void BeginCopyPass()
+ public CopyPass BeginCopyPass()
{
#if DEBUG
AssertNotSubmitted();
@@ -759,228 +802,15 @@ public class CommandBuffer
copyPassActive = true;
#endif
- Refresh.Refresh_BeginCopyPass(
- Device.Handle,
- Handle
- );
+ var copyPassHandle = SDL_Gpu.SDL_GpuBeginCopyPass(Handle);
+
+ var copyPass = Device.CopyPassPool.Obtain();
+ copyPass.SetHandle(copyPassHandle);
+
+ return copyPass;
}
-
- ///
- /// 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.
- ///
- /// Specifies data dependency behavior.
- 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
- );
- }
-
- ///
- /// Uploads the contents of an entire buffer to a texture with no mips.
- ///
- public void UploadToTexture(
- TransferBuffer transferBuffer,
- Texture texture,
- WriteOptions writeOption
- ) {
- UploadToTexture(
- transferBuffer,
- new TextureRegion(texture),
- new BufferImageCopy(0, 0, 0),
- writeOption
- );
- }
-
- ///
- /// 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.
- ///
- 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
- );
- }
-
- ///
- /// Copies the entire contents of a TransferBuffer to a GpuBuffer.
- ///
- public void UploadToBuffer(
- TransferBuffer transferBuffer,
- GpuBuffer gpuBuffer,
- WriteOptions option
- ) {
- UploadToBuffer(
- transferBuffer,
- gpuBuffer,
- new BufferCopy(0, 0, transferBuffer.Size),
- option
- );
- }
-
- ///
- /// Copies data element-wise into from a TransferBuffer to a GpuBuffer.
- ///
- public void UploadToBuffer(
- TransferBuffer transferBuffer,
- GpuBuffer gpuBuffer,
- uint sourceStartElement,
- uint destinationStartElement,
- uint numElements,
- WriteOptions option
- ) where T : unmanaged
- {
- var elementSize = Marshal.SizeOf();
- var dataLengthInBytes = (uint) (elementSize * numElements);
- var srcOffsetInBytes = (uint) (elementSize * sourceStartElement);
- var dstOffsetInBytes = (uint) (elementSize * destinationStartElement);
-
- UploadToBuffer(
- transferBuffer,
- gpuBuffer,
- new BufferCopy(
- srcOffsetInBytes,
- dstOffsetInBytes,
- dataLengthInBytes
- ),
- option
- );
- }
-
- ///
- /// 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.
- ///
- 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
- );
- }
-
- ///
- /// Copies the contents of an entire Texture with no mips to another Texture with no mips.
- /// The textures must have the same dimensions.
- ///
- public void CopyTextureToTexture(
- Texture source,
- Texture destination,
- WriteOptions option
- ) {
- CopyTextureToTexture(
- new TextureRegion(source),
- new TextureRegion(destination),
- option
- );
- }
-
- ///
- /// 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.
- ///
- 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
- );
- }
-
- ///
- /// Copies the entire contents of a GpuBuffer to another GpuBuffer.
- ///
- public void CopyBufferToBuffer(
- GpuBuffer source,
- GpuBuffer destination,
- WriteOptions option
- ) {
- CopyBufferToBuffer(
- source,
- destination,
- new BufferCopy(0, 0, source.Size),
- option
- );
- }
-
- public void EndCopyPass()
+ public void EndCopyPass(CopyPass copyPass)
{
#if DEBUG
AssertNotSubmitted();
@@ -988,10 +818,12 @@ public class CommandBuffer
copyPassActive = false;
#endif
- Refresh.Refresh_EndCopyPass(
- Device.Handle,
- Handle
+ SDL_Gpu.SDL_GpuEndCopyPass(
+ copyPass.Handle
);
+
+ copyPass.SetHandle(nint.Zero);
+ Device.CopyPassPool.Return(copyPass);
}
#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)
{
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!");
}
- 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!");
}
diff --git a/src/Graphics/CopyPass.cs b/src/Graphics/CopyPass.cs
new file mode 100644
index 0000000..de4de7e
--- /dev/null
+++ b/src/Graphics/CopyPass.cs
@@ -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;
+ }
+
+ ///
+ /// 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.
+ ///
+ /// If true, cycles the texture if the given slice is bound.
+ 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)
+ );
+ }
+
+ ///
+ /// Uploads the contents of an entire buffer to a 2D texture with no mips.
+ ///
+ public void UploadToTexture(
+ TransferBuffer transferBuffer,
+ Texture texture,
+ bool cycle
+ ) {
+ UploadToTexture(
+ transferBuffer,
+ new TextureRegion(texture),
+ new BufferImageCopy(0, 0, 0),
+ cycle
+ );
+ }
+
+ ///
+ /// 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.
+ ///
+ /// If true, cycles the buffer if it is bound.
+ 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)
+ );
+ }
+
+ ///
+ /// Copies the entire contents of a TransferBuffer to a GpuBuffer.
+ ///
+ public void UploadToBuffer(
+ TransferBuffer transferBuffer,
+ GpuBuffer buffer,
+ bool cycle
+ ) {
+ UploadToBuffer(
+ transferBuffer,
+ buffer,
+ new BufferCopy(0, 0, transferBuffer.Size),
+ cycle
+ );
+ }
+
+ ///
+ /// Copies data element-wise into from a TransferBuffer to a GpuBuffer.
+ ///
+ public void UploadToBuffer(
+ TransferBuffer transferBuffer,
+ GpuBuffer buffer,
+ uint sourceStartElement,
+ uint destinationStartElement,
+ uint numElements,
+ bool cycle
+ ) where T : unmanaged
+ {
+ var elementSize = Marshal.SizeOf();
+ var dataLengthInBytes = (uint) (elementSize * numElements);
+ var srcOffsetInBytes = (uint) (elementSize * sourceStartElement);
+ var dstOffsetInBytes = (uint) (elementSize * destinationStartElement);
+
+ UploadToBuffer(
+ transferBuffer,
+ buffer,
+ new BufferCopy(srcOffsetInBytes, dstOffsetInBytes, dataLengthInBytes),
+ cycle
+ );
+ }
+
+ ///
+ /// 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.
+ ///
+ 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)
+ );
+ }
+
+ ///
+ /// 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.
+ ///
+ 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
+}
diff --git a/src/Graphics/CopyPassPool.cs b/src/Graphics/CopyPassPool.cs
new file mode 100644
index 0000000..fde8097
--- /dev/null
+++ b/src/Graphics/CopyPassPool.cs
@@ -0,0 +1,25 @@
+using System.Collections.Concurrent;
+
+namespace MoonWorks.Graphics;
+
+internal class CopyPassPool
+{
+ private ConcurrentQueue CopyPasses = new ConcurrentQueue();
+
+ public CopyPass Obtain()
+ {
+ if (CopyPasses.TryDequeue(out var copyPass))
+ {
+ return copyPass;
+ }
+ else
+ {
+ return new CopyPass();
+ }
+ }
+
+ public void Return(CopyPass copyPass)
+ {
+ CopyPasses.Enqueue(copyPass);
+ }
+}
diff --git a/src/Graphics/GraphicsDevice.cs b/src/Graphics/GraphicsDevice.cs
index 92abfd7..fc01b24 100644
--- a/src/Graphics/GraphicsDevice.cs
+++ b/src/Graphics/GraphicsDevice.cs
@@ -41,6 +41,7 @@ namespace MoonWorks.Graphics
private FencePool FencePool;
internal RenderPassPool RenderPassPool;
internal ComputePassPool ComputePassPool;
+ internal CopyPassPool CopyPassPool;
internal unsafe GraphicsDevice(
BackendFlags preferredBackends,
diff --git a/src/Graphics/ImageUtils.cs b/src/Graphics/ImageUtils.cs
index 11ee4b7..c97e6da 100644
--- a/src/Graphics/ImageUtils.cs
+++ b/src/Graphics/ImageUtils.cs
@@ -2,6 +2,7 @@ using System;
using System.IO;
using System.Runtime.InteropServices;
using RefreshCS;
+using SDL2;
namespace MoonWorks.Graphics
{
diff --git a/src/Graphics/ResourceUploader.cs b/src/Graphics/ResourceUploader.cs
index 0475931..e2564ce 100644
--- a/src/Graphics/ResourceUploader.cs
+++ b/src/Graphics/ResourceUploader.cs
@@ -26,8 +26,8 @@ namespace MoonWorks.Graphics
uint textureDataOffset = 0;
uint textureDataSize = 1024;
- List<(GpuBuffer, BufferCopy, WriteOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, WriteOptions)>();
- List<(TextureRegion, uint, WriteOptions)> TextureUploads = new List<(TextureRegion, uint, WriteOptions)>();
+ List<(GpuBuffer, BufferCopy, bool)> BufferUploads = new List<(GpuBuffer, BufferCopy, bool)>();
+ List<(TextureRegion, uint, bool)> TextureUploads = new List<(TextureRegion, uint, bool)>();
public ResourceUploader(GraphicsDevice device) : base(device)
{
@@ -45,7 +45,7 @@ namespace MoonWorks.Graphics
var lengthInBytes = (uint) (Marshal.SizeOf() * data.Length);
var gpuBuffer = new GpuBuffer(Device, usageFlags, lengthInBytes);
- SetBufferData(gpuBuffer, 0, data, WriteOptions.Unsafe);
+ SetBufferData(gpuBuffer, 0, data, false);
return gpuBuffer;
}
@@ -53,7 +53,7 @@ namespace MoonWorks.Graphics
///
/// Prepares upload of data into a GpuBuffer.
///
- public void SetBufferData(GpuBuffer buffer, uint bufferOffsetInElements, Span data, WriteOptions option) where T : unmanaged
+ public void SetBufferData(GpuBuffer buffer, uint bufferOffsetInElements, Span data, bool cycle) where T : unmanaged
{
uint elementSize = (uint) Marshal.SizeOf();
uint offsetInBytes = elementSize * bufferOffsetInElements;
@@ -66,7 +66,7 @@ namespace MoonWorks.Graphics
}
var bufferCopyParams = new BufferCopy(resourceOffset, offsetInBytes, lengthInBytes);
- BufferUploads.Add((buffer, bufferCopyParams, option));
+ BufferUploads.Add((buffer, bufferCopyParams, cycle));
}
// Textures
@@ -74,7 +74,7 @@ namespace MoonWorks.Graphics
public Texture CreateTexture2D(Span pixelData, uint width, uint height) where T : unmanaged
{
var texture = Texture.CreateTexture2D(Device, width, height, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
- SetTextureData(texture, pixelData, WriteOptions.Unsafe);
+ SetTextureData(texture, pixelData, false);
return texture;
}
@@ -164,7 +164,7 @@ namespace MoonWorks.Graphics
Depth = 1
};
- SetTextureData(textureRegion, byteSpan, WriteOptions.Unsafe);
+ SetTextureData(textureRegion, byteSpan, false);
NativeMemory.Free(byteBuffer);
}
@@ -187,7 +187,7 @@ namespace MoonWorks.Graphics
var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes);
var pixelSpan = new Span((void*) pixelData, (int) sizeInBytes);
- SetTextureData(textureRegion, pixelSpan, WriteOptions.Unsafe);
+ SetTextureData(textureRegion, pixelSpan, false);
ImageUtils.FreePixelData(pixelData);
}
@@ -211,7 +211,7 @@ namespace MoonWorks.Graphics
///
/// Prepares upload of pixel data into a TextureSlice.
///
- public void SetTextureData(TextureRegion textureRegion, Span data, WriteOptions option) where T : unmanaged
+ public void SetTextureData(TextureRegion textureRegion, Span data, bool cycle) where T : unmanaged
{
var elementSize = Marshal.SizeOf();
var dataLengthInBytes = (uint) (elementSize * data.Length);
@@ -222,7 +222,7 @@ namespace MoonWorks.Graphics
resourceOffset = CopyTextureData(dataPtr, dataLengthInBytes, Texture.BytesPerPixel(textureRegion.TextureSlice.Texture.Format));
}
- TextureUploads.Add((textureRegion, resourceOffset, option));
+ TextureUploads.Add((textureRegion, resourceOffset, cycle));
}
// Upload
@@ -263,11 +263,11 @@ namespace MoonWorks.Graphics
if (BufferTransferBuffer == null || BufferTransferBuffer.Size < bufferDataSize)
{
BufferTransferBuffer?.Dispose();
- BufferTransferBuffer = new TransferBuffer(Device, TransferUsage.Buffer, bufferDataSize);
+ BufferTransferBuffer = new TransferBuffer(Device, TransferUsage.Buffer, TransferBufferMapFlags.Write, bufferDataSize);
}
var dataSpan = new Span(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)
{
TextureTransferBuffer?.Dispose();
- TextureTransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, textureDataSize);
+ TextureTransferBuffer = new TransferBuffer(Device, TransferUsage.Texture, TransferBufferMapFlags.Write, textureDataSize);
}
var dataSpan = new Span(textureData, (int) textureDataSize);
- TextureTransferBuffer.SetData(dataSpan, TransferOptions.Cycle);
+ TextureTransferBuffer.SetData(dataSpan, true);
}
}
private void RecordUploadCommands(CommandBuffer commandBuffer)
{
- commandBuffer.BeginCopyPass();
+ var copyPass = commandBuffer.BeginCopyPass();
foreach (var (gpuBuffer, bufferCopyParams, option) in BufferUploads)
{
- commandBuffer.UploadToBuffer(
+ copyPass.UploadToBuffer(
BufferTransferBuffer,
gpuBuffer,
bufferCopyParams,
@@ -300,7 +300,7 @@ namespace MoonWorks.Graphics
foreach (var (textureRegion, offset, option) in TextureUploads)
{
- commandBuffer.UploadToTexture(
+ copyPass.UploadToTexture(
TextureTransferBuffer,
textureRegion,
new BufferImageCopy(
@@ -312,7 +312,7 @@ namespace MoonWorks.Graphics
);
}
- commandBuffer.EndCopyPass();
+ commandBuffer.EndCopyPass(copyPass);
BufferUploads.Clear();
TextureUploads.Clear();
diff --git a/src/Graphics/Resources/Fence.cs b/src/Graphics/Resources/Fence.cs
index 2f61fdf..9f27c74 100644
--- a/src/Graphics/Resources/Fence.cs
+++ b/src/Graphics/Resources/Fence.cs
@@ -1,26 +1,25 @@
using System;
-using RefreshCS;
+using SDL2_gpuCS;
-namespace MoonWorks.Graphics
+namespace MoonWorks.Graphics;
+
+///
+/// Fences allow you to track the status of a submitted command buffer.
+/// You should only acquire a Fence if you will need to track the command buffer.
+/// You should make sure to call GraphicsDevice.ReleaseFence when done with a Fence to avoid memory growth.
+/// The Fence object itself is basically just a wrapper for the Refresh_Fence.
+/// The internal handle is replaced so that we can pool Fence objects to manage garbage.
+///
+public class Fence : SDL_GpuResource
{
- ///
- /// Fences allow you to track the status of a submitted command buffer.
- /// You should only acquire a Fence if you will need to track the command buffer.
- /// You should make sure to call GraphicsDevice.ReleaseFence when done with a Fence to avoid memory growth.
- /// The Fence object itself is basically just a wrapper for the Refresh_Fence.
- /// The internal handle is replaced so that we can pool Fence objects to manage garbage.
- ///
- public class Fence : SDL_GpuResource
+ protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseFence;
+
+ internal Fence(GraphicsDevice device) : base(device)
{
- protected override Action ReleaseFunction => Refresh.Refresh_ReleaseFence;
+ }
- internal Fence(GraphicsDevice device) : base(device)
- {
- }
-
- internal void SetHandle(nint handle)
- {
- Handle = handle;
- }
+ internal void SetHandle(nint handle)
+ {
+ Handle = handle;
}
}
diff --git a/src/Graphics/Resources/Sampler.cs b/src/Graphics/Resources/Sampler.cs
index 2386214..a20dbc7 100644
--- a/src/Graphics/Resources/Sampler.cs
+++ b/src/Graphics/Resources/Sampler.cs
@@ -1,24 +1,23 @@
using System;
-using RefreshCS;
+using SDL2_gpuCS;
-namespace MoonWorks.Graphics
+namespace MoonWorks.Graphics;
+
+///
+/// A sampler specifies how a texture will be sampled in a shader.
+///
+public class Sampler : SDL_GpuResource
{
- ///
- /// A sampler specifies how a texture will be sampled in a shader.
- ///
- public class Sampler : SDL_GpuResource
- {
- protected override Action ReleaseFunction => Refresh.Refresh_QueueDestroySampler;
+ protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseSampler;
- public Sampler(
- GraphicsDevice device,
- in SamplerCreateInfo samplerCreateInfo
- ) : base(device)
- {
- Handle = Refresh.Refresh_CreateSampler(
- device.Handle,
- samplerCreateInfo.ToRefreshSamplerStateCreateInfo()
- );
- }
+ public Sampler(
+ GraphicsDevice device,
+ in SamplerCreateInfo samplerCreateInfo
+ ) : base(device)
+ {
+ Handle = SDL_Gpu.SDL_GpuCreateSampler(
+ device.Handle,
+ samplerCreateInfo.ToSDL()
+ );
}
}
diff --git a/src/Graphics/Resources/TransferBuffer.cs b/src/Graphics/Resources/TransferBuffer.cs
index 3f2c070..a10bb01 100644
--- a/src/Graphics/Resources/TransferBuffer.cs
+++ b/src/Graphics/Resources/TransferBuffer.cs
@@ -1,12 +1,12 @@
using System;
using System.Runtime.InteropServices;
-using RefreshCS;
+using SDL2_gpuCS;
namespace MoonWorks.Graphics
{
public unsafe class TransferBuffer : SDL_GpuResource
{
- protected override Action ReleaseFunction => Refresh.Refresh_QueueDestroyTransferBuffer;
+ protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseTransferBuffer;
///
/// Size in bytes.
@@ -23,12 +23,14 @@ namespace MoonWorks.Graphics
public unsafe static TransferBuffer Create(
GraphicsDevice device,
TransferUsage usage,
+ TransferBufferMapFlags mapFlags,
uint elementCount
) where T : unmanaged
{
return new TransferBuffer(
device,
usage,
+ mapFlags,
(uint) Marshal.SizeOf() * elementCount
);
}
@@ -42,12 +44,14 @@ namespace MoonWorks.Graphics
public TransferBuffer(
GraphicsDevice device,
TransferUsage usage,
+ TransferBufferMapFlags mapFlags,
uint sizeInBytes
) : base(device)
{
- Handle = Refresh.Refresh_CreateTransferBuffer(
+ Handle = SDL_Gpu.SDL_GpuCreateTransferBuffer(
device.Handle,
- (Refresh.TransferUsage) usage,
+ (SDL_Gpu.TransferUsage) usage,
+ (SDL_Gpu.TransferBufferMapFlags) mapFlags,
sizeInBytes
);
Size = sizeInBytes;
@@ -57,16 +61,16 @@ namespace MoonWorks.Graphics
/// Immediately copies data from a Span to the TransferBuffer.
/// Returns the length of the copy in bytes.
///
- /// If setDataOption is DISCARD and this TransferBuffer was used in an Upload command,
- /// that command will still use the correct data at the cost of increased memory usage.
+ /// If cycle is set to true and this TransferBuffer was used in an Upload command,
+ /// 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,
- /// the data will be overwritten immediately, which could cause a data race.
+ /// If cycle is set to false, the data will be overwritten immediately,
+ /// which could cause a data race.
///
public unsafe uint SetData(
Span data,
uint bufferOffsetInBytes,
- TransferOptions setDataOption
+ bool cycle
) where T : unmanaged
{
var elementSize = Marshal.SizeOf();
@@ -78,17 +82,17 @@ namespace MoonWorks.Graphics
fixed (T* dataPtr = data)
{
- Refresh.Refresh_SetTransferData(
+ SDL_Gpu.SDL_GpuSetTransferData(
Device.Handle,
(nint) dataPtr,
Handle,
- new Refresh.BufferCopy
+ new SDL_Gpu.BufferCopy
{
- srcOffset = 0,
- dstOffset = bufferOffsetInBytes,
- size = dataLengthInBytes
+ SourceOffset = 0,
+ DestinationOffset = bufferOffsetInBytes,
+ Size = dataLengthInBytes
},
- (Refresh.TransferOptions) setDataOption
+ Conversions.BoolToInt(cycle)
);
}
@@ -99,18 +103,18 @@ namespace MoonWorks.Graphics
/// Immediately copies data from a Span to the TransferBuffer.
/// Returns the length of the copy in bytes.
///
- /// If setDataOption is DISCARD and this TransferBuffer was used in an Upload command,
- /// that command will still use the correct data at the cost of increased memory usage.
+ /// If cycle is set to true and this TransferBuffer was used in an Upload command,
+ /// 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,
- /// the data will be overwritten immediately, which could cause a data race.
+ /// If cycle is set to false, the data will be overwritten immediately,
+ /// which could cause a data race.
///
public unsafe uint SetData(
Span data,
- TransferOptions setDataOption
+ bool cycle
) where T : unmanaged
{
- return SetData(data, 0, setDataOption);
+ return SetData(data, 0, cycle);
}
///
@@ -130,15 +134,15 @@ namespace MoonWorks.Graphics
fixed (T* dataPtr = data)
{
- Refresh.Refresh_GetTransferData(
+ SDL_Gpu.SDL_GpuGetTransferData(
Device.Handle,
Handle,
(nint) dataPtr,
- new Refresh.BufferCopy
+ new SDL_Gpu.BufferCopy
{
- srcOffset = bufferOffsetInBytes,
- dstOffset = 0,
- size = dataLengthInBytes
+ SourceOffset = bufferOffsetInBytes,
+ DestinationOffset = 0,
+ Size = dataLengthInBytes
}
);
}
diff --git a/src/Graphics/SDL_GpuTypes.cs b/src/Graphics/SDL_GpuTypes.cs
index d5ac12d..4511226 100644
--- a/src/Graphics/SDL_GpuTypes.cs
+++ b/src/Graphics/SDL_GpuTypes.cs
@@ -788,7 +788,7 @@ public struct BufferCopy
Size = size;
}
- public SDL_Gpu.BufferCopy ToRefresh()
+ public SDL_Gpu.BufferCopy ToSDL()
{
return new SDL_Gpu.BufferCopy
{
@@ -811,7 +811,7 @@ public readonly record struct BufferImageCopy(
uint BufferStride,
uint BufferImageHeight
) {
- public SDL_Gpu.BufferImageCopy ToRefresh()
+ public SDL_Gpu.BufferImageCopy ToSDL()
{
return new SDL_Gpu.BufferImageCopy
{
diff --git a/src/Logger.cs b/src/Logger.cs
index 76821e7..2225e59 100644
--- a/src/Logger.cs
+++ b/src/Logger.cs
@@ -1,5 +1,4 @@
using System;
-using RefreshCS;
namespace MoonWorks
{
@@ -9,19 +8,6 @@ namespace MoonWorks
public static Action LogWarn = LogWarnDefault;
public static Action 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)
{
Console.ForegroundColor = ConsoleColor.Green;
diff --git a/src/WindowCreateInfo.cs b/src/WindowCreateInfo.cs
index 4439585..cf141d4 100644
--- a/src/WindowCreateInfo.cs
+++ b/src/WindowCreateInfo.cs
@@ -22,9 +22,13 @@
///
public ScreenMode ScreenMode;
///
+ /// Specifies the swapchain composition. Use SDR unless you know what you're doing.
+ ///
+ public Graphics.SwapchainComposition SwapchainComposition;
+ ///
/// Specifies the presentation mode for the window. Roughly equivalent to V-Sync.
///
- public PresentMode PresentMode;
+ public Graphics.PresentMode PresentMode;
///
/// Whether the window can be resized using the operating system's window dragging feature.
///
@@ -39,7 +43,7 @@
uint windowWidth,
uint windowHeight,
ScreenMode screenMode,
- PresentMode presentMode,
+ Graphics.PresentMode presentMode,
bool systemResizable = false,
bool startMaximized = false
) {