diff --git a/lib/RefreshCS b/lib/RefreshCS index 61ec63b7..d844fe56 160000 --- a/lib/RefreshCS +++ b/lib/RefreshCS @@ -1 +1 @@ -Subproject commit 61ec63b71f9fc3163ef5a8d985fbb53e3f02dbf9 +Subproject commit d844fe56ee16e7e0e0ae4f4ff1814292e499dff7 diff --git a/src/Graphics/CommandBuffer.cs b/src/Graphics/CommandBuffer.cs index f0d3cfbe..380b586d 100644 --- a/src/Graphics/CommandBuffer.cs +++ b/src/Graphics/CommandBuffer.cs @@ -52,12 +52,14 @@ namespace MoonWorks.Graphics refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh(); } + Rect renderArea = new Rect((int) colorAttachmentInfos[0].Texture.Width, (int) colorAttachmentInfos[0].Texture.Height); + fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos) { Refresh.Refresh_BeginRenderPass( Device.Handle, Handle, - colorAttachmentInfos[0].RenderTarget.TextureSlice.Rectangle.ToRefresh(), + renderArea.ToRefresh(), (IntPtr) pColorAttachmentInfos, (uint) colorAttachmentInfos.Length, IntPtr.Zero @@ -100,12 +102,14 @@ namespace MoonWorks.Graphics var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + Rect renderArea = new Rect((int) colorAttachmentInfos[0].Texture.Width, (int) colorAttachmentInfos[0].Texture.Height); + fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos) { Refresh.Refresh_BeginRenderPass( Device.Handle, Handle, - colorAttachmentInfos[0].RenderTarget.TextureSlice.Rectangle.ToRefresh(), + renderArea.ToRefresh(), pColorAttachmentInfos, (uint) colorAttachmentInfos.Length, &refreshDepthStencilAttachmentInfo @@ -650,126 +654,19 @@ namespace MoonWorks.Graphics } /// - /// Prepares a texture to be presented to a window. - /// This particular variant of this method will present to the entire window area. + /// Acquires a swapchain texture. + /// This texture will be presented to the given window when the command buffer is submitted. /// - /// The texture to present. - /// The filter to use when the texture size differs from the window size. - public void QueuePresent( - Texture texture, - Filter filter, + public Texture AcquireSwapchainTexture( Window window ) { - var refreshTextureSlice = new Refresh.TextureSlice - { - texture = texture.Handle, - rectangle = new Refresh.Rect - { - x = 0, - y = 0, - w = (int) texture.Width, - h = (int) texture.Height - }, - layer = 0, - level = 0, - depth = 0 - }; - - Refresh.Refresh_QueuePresent( - Device.Handle, - Handle, - refreshTextureSlice, - IntPtr.Zero, - (Refresh.Filter) filter, - window.Handle - ); - } - - /// - /// Prepares a texture slice to be presented to a window. - /// This particular variant of this method will present to the entire window area. - /// - /// The texture slice to present. - /// The filter to use when the texture size differs from the window size. - public void QueuePresent( - in TextureSlice textureSlice, - Filter filter, - Window window - ) - { - Refresh.Refresh_QueuePresent( - Device.Handle, - Handle, - textureSlice.ToRefreshTextureSlice(), - IntPtr.Zero, - (Refresh.Filter) filter, - window.Handle - ); - } - - /// - /// Prepares a texture to be presented to a window. - /// - /// The texture to present. - /// The area of the window to present to. - /// The filter to use when the texture size differs from the destination rectangle. - public void QueuePresent( - in Texture texture, - in Rect destinationRectangle, - Filter filter, - Window window - ) - { - var refreshRect = destinationRectangle.ToRefresh(); - var refreshTextureSlice = new Refresh.TextureSlice - { - texture = texture.Handle, - rectangle = new Refresh.Rect - { - x = 0, - y = 0, - w = (int) texture.Width, - h = (int) texture.Height - }, - layer = 0, - level = 0, - depth = 0 - }; - - Refresh.Refresh_QueuePresent( - Device.Handle, - Handle, - refreshTextureSlice, - refreshRect, - (Refresh.Filter) filter, - window.Handle - ); - } - - /// - /// Prepares a texture slice to be presented to a window. - /// - /// The texture slice to present. - /// The area of the window to present to. - /// The filter to use when the texture size differs from the destination rectangle. - public void QueuePresent( - in TextureSlice textureSlice, - in Rect destinationRectangle, - Filter filter, - Window window - ) - { - var refreshTextureSlice = textureSlice.ToRefreshTextureSlice(); - var refreshRect = destinationRectangle.ToRefresh(); - - Refresh.Refresh_QueuePresent( - Device.Handle, - Handle, - refreshTextureSlice, - refreshRect, - (Refresh.Filter) filter, - window.Handle + return new Texture( + Device, + Refresh.Refresh_AcquireSwapchainTexture(Device.Handle, Handle, window.Handle), + (TextureFormat) Refresh.Refresh_GetSwapchainFormat(Device.Handle, window.Handle), + window.Width, + window.Height ); } diff --git a/src/Graphics/RefreshEnums.cs b/src/Graphics/RefreshEnums.cs index 4ec22845..f854e3e8 100644 --- a/src/Graphics/RefreshEnums.cs +++ b/src/Graphics/RefreshEnums.cs @@ -60,6 +60,7 @@ namespace MoonWorks.Graphics public enum TextureFormat { R8G8B8A8, + B8G8R8A8, R5G6B5, A1R5G5B5, B4G4R4A4, diff --git a/src/Graphics/RefreshStructs.cs b/src/Graphics/RefreshStructs.cs index 8af0cc98..4f0ef762 100644 --- a/src/Graphics/RefreshStructs.cs +++ b/src/Graphics/RefreshStructs.cs @@ -148,7 +148,11 @@ namespace MoonWorks.Graphics [StructLayout(LayoutKind.Sequential)] public struct ColorAttachmentInfo { - public RenderTarget RenderTarget; + public Texture Texture; + public uint Depth; + public uint Layer; + public uint Level; + public SampleCount SampleCount; public Color ClearColor; public LoadOp LoadOp; public StoreOp StoreOp; @@ -157,7 +161,11 @@ namespace MoonWorks.Graphics { return new Refresh.ColorAttachmentInfo { - renderTarget = RenderTarget.Handle, + texture = Texture.Handle, + depth = Depth, + layer = Layer, + level = Level, + sampleCount = (Refresh.SampleCount) SampleCount, clearColor = new Refresh.Vec4 { x = ClearColor.R / 255f, @@ -174,8 +182,11 @@ namespace MoonWorks.Graphics [StructLayout(LayoutKind.Sequential)] public struct DepthStencilAttachmentInfo { - public RenderTarget DepthStencilTarget; - public DepthStencilValue DepthStencilValue; + public Texture Texture; + public uint Depth; + public uint Layer; + public uint Level; + public DepthStencilValue DepthStencilClearValue; public LoadOp LoadOp; public StoreOp StoreOp; public LoadOp StencilLoadOp; @@ -185,8 +196,11 @@ namespace MoonWorks.Graphics { return new Refresh.DepthStencilAttachmentInfo { - depthStencilTarget = DepthStencilTarget.Handle, - depthStencilValue = DepthStencilValue.ToRefresh(), + texture = Texture.Handle, + depth = Depth, + layer = Layer, + level = Level, + depthStencilClearValue = DepthStencilClearValue.ToRefresh(), loadOp = (Refresh.LoadOp) LoadOp, storeOp = (Refresh.StoreOp) StoreOp, stencilLoadOp = (Refresh.LoadOp) StencilLoadOp, diff --git a/src/Graphics/Resources/RenderTarget.cs b/src/Graphics/Resources/RenderTarget.cs deleted file mode 100644 index 06964c16..00000000 --- a/src/Graphics/Resources/RenderTarget.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using RefreshCS; - -namespace MoonWorks.Graphics -{ - /// - /// A render target is a structure that wraps a texture so that it can be rendered to. - /// - public class RenderTarget : GraphicsResource - { - public TextureSlice TextureSlice { get; } - public TextureFormat Format => TextureSlice.Texture.Format; - - public uint Width => (uint) TextureSlice.Rectangle.W; - public uint Height => (uint) TextureSlice.Rectangle.H; - - protected override Action QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderTarget; - - /// - /// Creates a render target backed by a texture. - /// - /// An initialized GraphicsDevice. - /// The width of the render target. - /// The height of the render target. - /// The format of the render target. - /// Whether the render target can be used by a sampler. - /// The multisample count of the render target. - /// The mip level of the render target. - /// - public static RenderTarget CreateBackedRenderTarget( - GraphicsDevice device, - uint width, - uint height, - TextureFormat format, - bool canBeSampled, - SampleCount sampleCount = SampleCount.One, - uint levelCount = 1 - ) - { - TextureUsageFlags flags = 0; - - if ( - format == TextureFormat.D16 || - format == TextureFormat.D32 || - format == TextureFormat.D16S8 || - format == TextureFormat.D32S8 - ) - { - flags |= TextureUsageFlags.DepthStencilTarget; - } - else - { - flags |= TextureUsageFlags.ColorTarget; - } - - if (canBeSampled) - { - flags |= TextureUsageFlags.Sampler; - } - - var texture = Texture.CreateTexture2D( - device, - width, - height, - format, - flags, - sampleCount, - levelCount - ); - - return new RenderTarget(device, new TextureSlice(texture), sampleCount); - } - - /// - /// Creates a render target using a texture slice and an optional sample count. - /// - /// An initialized GraphicsDevice. - /// The texture slice that will be rendered to. - /// The desired multisample count of the render target. - public RenderTarget( - GraphicsDevice device, - in TextureSlice textureSlice, - SampleCount sampleCount = SampleCount.One - ) : base(device) - { - Handle = Refresh.Refresh_CreateRenderTarget( - device.Handle, - textureSlice.ToRefreshTextureSlice(), - (Refresh.SampleCount) sampleCount - ); - TextureSlice = textureSlice; - } - } -} diff --git a/src/Graphics/Resources/Texture.cs b/src/Graphics/Resources/Texture.cs index fcd41144..1e8ff79d 100644 --- a/src/Graphics/Resources/Texture.cs +++ b/src/Graphics/Resources/Texture.cs @@ -56,11 +56,16 @@ namespace MoonWorks.Graphics return texture; } - public unsafe static void SavePNG(string path, int width, int height, byte[] pixels) + public unsafe static void SavePNG(string path, int width, int height, TextureFormat format, byte[] pixels) { + if (format != TextureFormat.R8G8B8A8 && format != TextureFormat.B8G8R8A8) + { + throw new ArgumentException("Texture format must be RGBA8 or BGRA8!", "format"); + } + fixed (byte* ptr = &pixels[0]) { - Refresh.Refresh_Image_SavePNG(path, width, height, (IntPtr) ptr); + Refresh.Refresh_Image_SavePNG(path, width, height, Conversions.BoolToByte(format == TextureFormat.B8G8R8A8), (IntPtr) ptr); } } @@ -191,8 +196,28 @@ namespace MoonWorks.Graphics IsCube = textureCreateInfo.IsCube; SampleCount = textureCreateInfo.SampleCount; LevelCount = textureCreateInfo.LevelCount; - SampleCount = textureCreateInfo.SampleCount; UsageFlags = textureCreateInfo.UsageFlags; } + + // Used by AcquireSwapchainTexture. + internal Texture( + GraphicsDevice device, + IntPtr handle, + TextureFormat format, + uint width, + uint height + ) : base(device) + { + Handle = handle; + + Format = format; + Width = width; + Height = height; + Depth = 1; + IsCube = false; + SampleCount = SampleCount.One; + LevelCount = 1; + UsageFlags = TextureUsageFlags.ColorTarget; + } } } diff --git a/src/OSWindow.cs b/src/Window.cs similarity index 100% rename from src/OSWindow.cs rename to src/Window.cs