From eab282cdca1442db14cddfe87909c10f6e26b060 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 4 Jun 2024 16:04:19 -0700 Subject: [PATCH] refactor RenderPass structure --- lib/SDL2_gpuCS | 2 +- src/Graphics/Bindings/BufferBinding.cs | 2 +- src/Graphics/CommandBuffer.cs | 792 +++++------------- src/Graphics/GraphicsDevice.cs | 11 +- src/Graphics/RenderPass.cs | 472 ++++++----- src/Graphics/RenderPassPool.cs | 26 + src/Graphics/Resources/GpuBuffer.cs | 144 ++-- src/Graphics/Resources/GraphicsPipeline.cs | 129 ++- src/Graphics/Resources/Texture.cs | 10 +- src/Graphics/SDL_GpuTypes.cs | 156 ++-- .../State/ColorAttachmentBlendState.cs | 22 +- src/Graphics/State/DepthStencilState.cs | 23 +- .../State/GraphicsPipelineAttachmentInfo.cs | 2 +- .../State/GraphicsPipelineCreateInfo.cs | 18 - src/Graphics/State/GraphicsShaderInfo.cs | 44 - src/Graphics/State/MultisampleState.cs | 13 +- src/Graphics/State/RasterizerState.cs | 199 +++-- src/Graphics/State/TextureCreateInfo.cs | 24 +- src/Graphics/TextureRegion.cs | 20 +- 19 files changed, 913 insertions(+), 1196 deletions(-) create mode 100644 src/Graphics/RenderPassPool.cs delete mode 100644 src/Graphics/State/GraphicsPipelineCreateInfo.cs delete mode 100644 src/Graphics/State/GraphicsShaderInfo.cs diff --git a/lib/SDL2_gpuCS b/lib/SDL2_gpuCS index 2866dd2..60e2c21 160000 --- a/lib/SDL2_gpuCS +++ b/lib/SDL2_gpuCS @@ -1 +1 @@ -Subproject commit 2866dd2a7d4ffd4366bd4885e04c68cf4b485b55 +Subproject commit 60e2c21a7b224dc6aa6a457dbb71d798a4e66241 diff --git a/src/Graphics/Bindings/BufferBinding.cs b/src/Graphics/Bindings/BufferBinding.cs index 5412c49..caadfb0 100644 --- a/src/Graphics/Bindings/BufferBinding.cs +++ b/src/Graphics/Bindings/BufferBinding.cs @@ -8,7 +8,7 @@ public readonly record struct BufferBinding( GpuBuffer Buffer, uint Offset ) { - public SDL_Gpu.BufferBinding ToRefresh() + public SDL_Gpu.BufferBinding ToSDL() { return new SDL_Gpu.BufferBinding { diff --git a/src/Graphics/CommandBuffer.cs b/src/Graphics/CommandBuffer.cs index 2dd72da..74b8719 100644 --- a/src/Graphics/CommandBuffer.cs +++ b/src/Graphics/CommandBuffer.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.InteropServices; +using SDL2; using SDL2_gpuCS; namespace MoonWorks.Graphics; @@ -16,21 +17,10 @@ public class CommandBuffer #if DEBUG bool swapchainTextureAcquired; - GraphicsPipeline currentGraphicsPipeline; ComputePipeline currentComputePipeline; + bool renderPassActive; - SampleCount colorAttachmentSampleCount; - uint colorAttachmentCount; - TextureFormat colorFormatOne; - TextureFormat colorFormatTwo; - TextureFormat colorFormatThree; - TextureFormat colorFormatFour; - bool hasDepthStencilAttachment; - SampleCount depthStencilAttachmentSampleCount; - TextureFormat depthStencilFormat; - bool copyPassActive; - bool computePassActive; internal bool Submitted; @@ -57,18 +47,9 @@ public class CommandBuffer { swapchainTextureAcquired = false; - currentGraphicsPipeline = null; currentComputePipeline = null; - renderPassActive = false; - colorAttachmentSampleCount = SampleCount.One; - depthStencilAttachmentSampleCount = SampleCount.One; - colorAttachmentCount = 0; - colorFormatOne = TextureFormat.R8G8B8A8; - colorFormatTwo = TextureFormat.R8G8B8A8; - colorFormatThree = TextureFormat.R8G8B8A8; - colorFormatFour = TextureFormat.R8G8B8A8; - depthStencilFormat = TextureFormat.D16; + renderPassActive = false; copyPassActive = false; computePassActive = false; @@ -132,7 +113,7 @@ public class CommandBuffer /// It is an error to call this during any kind of pass. /// /// The color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in ColorAttachmentInfo colorAttachmentInfo ) { #if DEBUG @@ -142,23 +123,28 @@ public class CommandBuffer AssertColorTarget(colorAttachmentInfo); #endif - var refreshColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[1]; - refreshColorAttachmentInfos[0] = colorAttachmentInfo.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[1]; + sdlColorAttachmentInfos[0] = colorAttachmentInfo.ToSDL(); - SDL_Gpu.SDL_GpuBeginRenderPass( + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - (IntPtr) refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 1, - IntPtr.Zero + (SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = false; - colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 1; - colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format; + renderPass.colorAttachmentCount = 1; + renderPass.colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = false; #endif + + return renderPass; } /// @@ -168,12 +154,14 @@ public class CommandBuffer /// /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo ) { #if DEBUG AssertNotSubmitted(); + AssertNotInPass("Cannot begin a render pass inside another pass!"); + AssertTextureNotNull(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne); @@ -183,26 +171,30 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[2]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[2]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - (IntPtr) refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 2, - IntPtr.Zero + (SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = false; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 2; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorAttachmentCount = 2; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = false; #endif + + return renderPass; } /// @@ -213,13 +205,14 @@ public class CommandBuffer /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo, in ColorAttachmentInfo colorAttachmentInfoThree ) { #if DEBUG AssertNotSubmitted(); + AssertNotInPass("Cannot begin a render pass inside another pass!"); AssertTextureNotNull(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne); @@ -234,28 +227,32 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[3]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); - refreshColorAttachmentInfos[2] = colorAttachmentInfoThree.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[3]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); + sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - (IntPtr) refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 3, - IntPtr.Zero + (SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = false; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 3; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; - colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; + renderPass.colorAttachmentCount = 3; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = false; #endif + + return renderPass; } /// @@ -267,7 +264,7 @@ public class CommandBuffer /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. /// The four color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo, in ColorAttachmentInfo colorAttachmentInfoThree, @@ -293,30 +290,34 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoFour.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[4]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); - refreshColorAttachmentInfos[2] = colorAttachmentInfoThree.ToRefresh(); - refreshColorAttachmentInfos[3] = colorAttachmentInfoFour.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[4]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); + sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL(); + sdlColorAttachmentInfos[3] = colorAttachmentInfoFour.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - (IntPtr) refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 4, - IntPtr.Zero + (SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = false; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 4; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; - colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; - colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format; + renderPass.colorAttachmentCount = 3; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; + renderPass.colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = false; #endif + + return renderPass; } /// @@ -325,7 +326,7 @@ public class CommandBuffer /// It is an error to call this after calling BeginRenderPass but before calling EndRenderPass. /// /// The depth stencil attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in DepthStencilAttachmentInfo depthStencilAttachmentInfo ) { #if DEBUG @@ -333,22 +334,26 @@ public class CommandBuffer AssertValidDepthAttachment(depthStencilAttachmentInfo); #endif - var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - (Refresh.ColorAttachmentInfo*) IntPtr.Zero, + (SDL_Gpu.ColorAttachmentInfo*) nint.Zero, 0, - &refreshDepthStencilAttachmentInfo + &sdlDepthStencilAttachmentInfo ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = true; - depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; - depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = true; + renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; #endif + + return renderPass; } /// @@ -358,7 +363,7 @@ public class CommandBuffer /// /// The depth stencil attachment to use in the render pass. /// The color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in DepthStencilAttachmentInfo depthStencilAttachmentInfo, in ColorAttachmentInfo colorAttachmentInfo ) { @@ -371,28 +376,32 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfo.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[1]; - refreshColorAttachmentInfos[0] = colorAttachmentInfo.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[1]; + sdlColorAttachmentInfos[0] = colorAttachmentInfo.ToSDL(); - var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 1, - &refreshDepthStencilAttachmentInfo + &sdlDepthStencilAttachmentInfo ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = true; - colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 1; - depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; - colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format; - depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = true; + renderPass.colorAttachmentCount = 1; + renderPass.colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format; + renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; #endif + + return renderPass; } /// @@ -403,7 +412,7 @@ public class CommandBuffer /// The depth stencil attachment to use in the render pass. /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in DepthStencilAttachmentInfo depthStencilAttachmentInfo, in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo @@ -422,29 +431,34 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[2]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[2]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); - var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 2, - &refreshDepthStencilAttachmentInfo + &sdlDepthStencilAttachmentInfo ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = true; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 2; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; - depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = true; + renderPass.colorAttachmentCount = 2; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; #endif + + return renderPass; } /// @@ -456,7 +470,7 @@ public class CommandBuffer /// The first color attachment to use in the render pass. /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in DepthStencilAttachmentInfo depthStencilAttachmentInfo, in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo, @@ -476,35 +490,40 @@ public class CommandBuffer AssertColorTarget(colorAttachmentInfoThree); AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture); - AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture); + AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture); AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[3]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); - refreshColorAttachmentInfos[2] = colorAttachmentInfoThree.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[3]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); + sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL(); - var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 3, - &refreshDepthStencilAttachmentInfo + &sdlDepthStencilAttachmentInfo ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = true; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 3; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; - colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; - depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; + renderPass.hasDepthStencilAttachment = true; + renderPass.colorAttachmentCount = 3; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; + renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; #endif + + return renderPass; } /// @@ -517,7 +536,7 @@ public class CommandBuffer /// The second color attachment to use in the render pass. /// The third color attachment to use in the render pass. /// The four color attachment to use in the render pass. - public unsafe void BeginRenderPass( + public unsafe RenderPass BeginRenderPass( in DepthStencilAttachmentInfo depthStencilAttachmentInfo, in ColorAttachmentInfo colorAttachmentInfoOne, in ColorAttachmentInfo colorAttachmentInfoTwo, @@ -546,418 +565,59 @@ public class CommandBuffer AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture); #endif - var refreshColorAttachmentInfos = stackalloc Refresh.ColorAttachmentInfo[4]; - refreshColorAttachmentInfos[0] = colorAttachmentInfoOne.ToRefresh(); - refreshColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToRefresh(); - refreshColorAttachmentInfos[2] = colorAttachmentInfoThree.ToRefresh(); - refreshColorAttachmentInfos[3] = colorAttachmentInfoFour.ToRefresh(); + var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[4]; + sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL(); + sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL(); + sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL(); + sdlColorAttachmentInfos[3] = colorAttachmentInfoFour.ToSDL(); - var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh(); + var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL(); - Refresh.Refresh_BeginRenderPass( - Device.Handle, + var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass( Handle, - refreshColorAttachmentInfos, + sdlColorAttachmentInfos, 4, - &refreshDepthStencilAttachmentInfo + &sdlDepthStencilAttachmentInfo ); + var renderPass = Device.RenderPassPool.Obtain(); + renderPass.SetHandle(renderPassHandle); + #if DEBUG renderPassActive = true; - hasDepthStencilAttachment = true; - colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; - colorAttachmentCount = 4; - colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; - colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; - colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; - colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format; - depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; -#endif - } - - /// - /// Binds samplers to be used by the fragment shader. - /// - /// The texture-sampler to bind. - public unsafe void BindFragmentSamplers( - in TextureSamplerBinding textureSamplerBinding - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - AssertFragmentSamplerCount(1); - AssertTextureSamplerBindingNonNull(textureSamplerBinding); - AssertTextureBindingUsageFlags(textureSamplerBinding.Texture); + renderPass.hasDepthStencilAttachment = true; + renderPass.colorAttachmentCount = 4; + renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount; + renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format; + renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format; + renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format; + renderPass.colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format; + renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount; + renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format; #endif - var bindingArray = stackalloc Refresh.TextureSamplerBinding[1]; - bindingArray[0] = textureSamplerBinding.ToRefresh(); - - Refresh.Refresh_BindFragmentSamplers( - Device.Handle, - Handle, - bindingArray - ); - } - - /// - /// Binds samplers to be used by the fragment shader. - /// - /// The first texture-sampler to bind. - /// The second texture-sampler to bind. - public unsafe void BindFragmentSamplers( - in TextureSamplerBinding textureSamplerBindingOne, - in TextureSamplerBinding textureSamplerBindingTwo - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - AssertFragmentSamplerCount(2); - AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); - AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); - AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); -#endif - - var bindingArray = stackalloc Refresh.TextureSamplerBinding[2]; - bindingArray[0] = textureSamplerBindingOne.ToRefresh(); - bindingArray[1] = textureSamplerBindingTwo.ToRefresh(); - - Refresh.Refresh_BindFragmentSamplers( - Device.Handle, - Handle, - bindingArray - ); - } - - /// - /// Binds samplers to be used by the fragment shader. - /// - /// The first texture-sampler to bind. - /// The second texture-sampler to bind. - /// The third texture-sampler to bind. - public unsafe void BindFragmentSamplers( - in TextureSamplerBinding textureSamplerBindingOne, - in TextureSamplerBinding textureSamplerBindingTwo, - in TextureSamplerBinding textureSamplerBindingThree - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - AssertFragmentSamplerCount(3); - AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); - AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); - AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); - AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); -#endif - - var bindingArray = stackalloc Refresh.TextureSamplerBinding[3]; - bindingArray[0] = textureSamplerBindingOne.ToRefresh(); - bindingArray[1] = textureSamplerBindingTwo.ToRefresh(); - bindingArray[2] = textureSamplerBindingThree.ToRefresh(); - - Refresh.Refresh_BindFragmentSamplers( - Device.Handle, - Handle, - bindingArray - ); - } - - /// - /// Binds samplers to be used by the fragment shader. - /// - /// The first texture-sampler to bind. - /// The second texture-sampler to bind. - /// The third texture-sampler to bind. - /// The fourth texture-sampler to bind. - public unsafe void BindFragmentSamplers( - in TextureSamplerBinding textureSamplerBindingOne, - in TextureSamplerBinding textureSamplerBindingTwo, - in TextureSamplerBinding textureSamplerBindingThree, - in TextureSamplerBinding textureSamplerBindingFour - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - AssertFragmentSamplerCount(4); - AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); - AssertTextureSamplerBindingNonNull(textureSamplerBindingTwo); - AssertTextureSamplerBindingNonNull(textureSamplerBindingThree); - AssertTextureSamplerBindingNonNull(textureSamplerBindingFour); - AssertTextureBindingUsageFlags(textureSamplerBindingOne.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); - AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture); -#endif - - var bindingArray = stackalloc Refresh.TextureSamplerBinding[4]; - bindingArray[0] = textureSamplerBindingOne.ToRefresh(); - bindingArray[1] = textureSamplerBindingTwo.ToRefresh(); - bindingArray[2] = textureSamplerBindingThree.ToRefresh(); - bindingArray[3] = textureSamplerBindingFour.ToRefresh(); - - Refresh.Refresh_BindFragmentSamplers( - Device.Handle, - Handle, - bindingArray - ); - } - - /// - /// Binds samplers to be used by the fragment shader. - /// - /// The texture-sampler pairs to bind. - public unsafe void BindFragmentSamplers( - in Span textureSamplerBindings - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - AssertFragmentSamplerCount(textureSamplerBindings.Length); -#endif - - Refresh.TextureSamplerBinding* bindingArray = (Refresh.TextureSamplerBinding*) NativeMemory.Alloc((nuint) (Marshal.SizeOf() * textureSamplerBindings.Length)); - - for (var i = 0; i < textureSamplerBindings.Length; i += 1) - { -#if DEBUG - AssertTextureSamplerBindingNonNull(textureSamplerBindings[i]); - AssertTextureBindingUsageFlags(textureSamplerBindings[i].Texture); -#endif - - bindingArray[i] = textureSamplerBindings[i].ToRefresh(); - } - - Refresh.Refresh_BindFragmentSamplers( - Device.Handle, - Handle, - bindingArray - ); - - NativeMemory.Free(bindingArray); - } - - /// - /// Pushes vertex shader uniforms to the device. - /// - /// A starting offset value to be used with draw calls. - public unsafe void PushVertexShaderUniforms( - void* uniformsPtr, - uint size - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - - if (currentGraphicsPipeline.VertexShaderInfo.UniformBufferSize == 0) - { - throw new InvalidOperationException("The current vertex shader does not take a uniform buffer!"); - } - - if (currentGraphicsPipeline.VertexShaderInfo.UniformBufferSize != size) - { - throw new InvalidOperationException("Vertex uniform data size mismatch!"); - } -#endif - - Refresh.Refresh_PushVertexShaderUniforms( - Device.Handle, - Handle, - (IntPtr) uniformsPtr, - size - ); - } - - /// - /// Pushes vertex shader uniforms to the device. - /// - /// A starting offset value to be used with draw calls. - public unsafe void PushVertexShaderUniforms( - in T uniforms - ) where T : unmanaged - { - fixed (T* uniformsPtr = &uniforms) - { - PushVertexShaderUniforms(uniformsPtr, (uint) Marshal.SizeOf()); - } - } - - /// - /// Pushes fragment shader uniforms to the device. - /// - /// A starting offset to be used with draw calls. - public unsafe void PushFragmentShaderUniforms( - void* uniformsPtr, - uint size - ) { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); - - if (currentGraphicsPipeline.FragmentShaderInfo.UniformBufferSize == 0) - { - throw new InvalidOperationException("The current fragment shader does not take a uniform buffer!"); - } - - if (currentGraphicsPipeline.FragmentShaderInfo.UniformBufferSize != size) - { - throw new InvalidOperationException("Fragment uniform data size mismatch!"); - } -#endif - - Refresh.Refresh_PushFragmentShaderUniforms( - Device.Handle, - Handle, - (IntPtr) uniformsPtr, - size - ); - } - - /// - /// Pushes fragment shader uniforms to the device. - /// - /// A starting offset to be used with draw calls. - public unsafe void PushFragmentShaderUniforms( - in T uniforms - ) where T : unmanaged - { - fixed (T* uniformsPtr = &uniforms) - { - PushFragmentShaderUniforms(uniformsPtr, (uint) Marshal.SizeOf()); - } - } - - /// - /// Draws using instanced rendering. - /// - /// The starting index offset for the vertex buffer. - /// The starting index offset for the index buffer. - /// The number of primitives to draw. - /// The number of instances to draw. - public void DrawInstancedPrimitives( - uint baseVertex, - uint startIndex, - uint primitiveCount, - uint instanceCount - ) - { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); -#endif - - Refresh.Refresh_DrawInstancedPrimitives( - Device.Handle, - Handle, - baseVertex, - startIndex, - primitiveCount, - instanceCount - ); - } - - /// - /// Draws using a vertex buffer and an index buffer. - /// - /// The starting index offset for the vertex buffer. - /// The starting index offset for the index buffer. - /// The number of primitives to draw. - public void DrawIndexedPrimitives( - uint baseVertex, - uint startIndex, - uint primitiveCount - ) - { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); -#endif - - Refresh.Refresh_DrawInstancedPrimitives( - Device.Handle, - Handle, - baseVertex, - startIndex, - primitiveCount, - 1 - ); - } - - /// - /// Draws using a vertex buffer. - /// - /// - /// - public void DrawPrimitives( - uint vertexStart, - uint primitiveCount - ) - { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); -#endif - - Refresh.Refresh_DrawPrimitives( - Device.Handle, - Handle, - vertexStart, - primitiveCount - ); - } - - /// - /// Similar to DrawPrimitives, but parameters are set from a buffer. - /// - /// The draw parameters buffer. - /// The offset to start reading from the draw parameters buffer. - /// The number of draw parameter sets that should be read from the buffer. - /// The byte stride between sets of draw parameters. - /// An offset value obtained from PushVertexShaderUniforms. If no uniforms are required then use 0. - /// An offset value obtained from PushFragmentShaderUniforms. If no uniforms are required the use 0. - public void DrawPrimitivesIndirect( - GpuBuffer buffer, - uint offsetInBytes, - uint drawCount, - uint stride - ) - { -#if DEBUG - AssertNotSubmitted(); - AssertGraphicsPipelineBound(); -#endif - - Refresh.Refresh_DrawPrimitivesIndirect( - Device.Handle, - Handle, - buffer.Handle, - offsetInBytes, - drawCount, - stride - ); + return renderPass; } /// /// Ends the current render pass. /// This must be called before beginning another render pass or submitting the command buffer. /// - public void EndRenderPass() + public void EndRenderPass(RenderPass renderPass) { #if DEBUG AssertNotSubmitted(); + AssertRenderPassActive(); + + renderPassActive = false; + renderPass.active = false; #endif - Refresh.Refresh_EndRenderPass( - Device.Handle, - Handle + SDL_Gpu.SDL_GpuEndRenderPass( + renderPass.Handle ); -#if DEBUG - currentGraphicsPipeline = null; - renderPassActive = false; -#endif + Device.RenderPassPool.Return(renderPass); } /// @@ -965,23 +625,20 @@ public class CommandBuffer /// /// This operation cannot be performed inside any pass. /// - /// Specifies data dependency behavior. + /// If true, the destination texture will cycle if bound. public void Blit( - TextureRegion source, - TextureRegion destination, + in TextureRegion source, + in TextureRegion destination, Filter filter, - WriteOptions writeOption + bool cycle ) { - var sampler = filter == Filter.Linear ? Device.LinearSampler : Device.PointSampler; - - // FIXME: this will break with non-2D textures - // FIXME: the source texture region does nothing right now - BeginRenderPass(new ColorAttachmentInfo(destination.TextureSlice, writeOption)); - SetViewport(new Viewport(destination.X, destination.Y, destination.Width, destination.Height)); - BindGraphicsPipeline(Device.BlitPipeline); - BindFragmentSamplers(new TextureSamplerBinding(source.TextureSlice.Texture, sampler)); - DrawPrimitives(0, 2); - EndRenderPass(); + SDL_Gpu.SDL_GpuBlit( + Handle, + source.ToSDL(), + destination.ToSDL(), + (SDL_Gpu.Filter) filter, + Conversions.BoolToInt(cycle) + ); } public void BeginComputePass() @@ -1641,38 +1298,6 @@ public class CommandBuffer } } - private void AssertRenderPassInactive(string message = "Render pass is active!") - { - if (renderPassActive) - { - throw new System.InvalidCastException(message); - } - } - - private void AssertGraphicsPipelineBound(string message = "No graphics pipeline is bound!") - { - if (currentGraphicsPipeline == null) - { - throw new System.InvalidOperationException(message); - } - } - - private void AssertVertexSamplerCount(int count) - { - if (currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount != count) - { - throw new System.InvalidOperationException($"Vertex sampler expected {currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount} samplers, but received {count}"); - } - } - - private void AssertFragmentSamplerCount(int count) - { - if (currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount != count) - { - throw new System.InvalidOperationException($"Fragment sampler expected {currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount} samplers, but received {count}"); - } - } - private void AssertComputePipelineBound(string message = "No compute pipeline is bound!") { if (currentComputePipeline == null) @@ -1735,27 +1360,6 @@ public class CommandBuffer } } - private void AssertTextureSamplerBindingNonNull(in TextureSamplerBinding binding) - { - if (binding.Texture == null || binding.Texture.Handle == IntPtr.Zero) - { - throw new NullReferenceException("Texture binding must not be null!"); - } - - if (binding.Sampler == null || binding.Sampler.Handle == IntPtr.Zero) - { - throw new NullReferenceException("Sampler binding must not be null!"); - } - } - - private void AssertTextureBindingUsageFlags(Texture texture) - { - if ((texture.UsageFlags & TextureUsageFlags.Sampler) == 0) - { - throw new System.ArgumentException("The bound Texture's UsageFlags must include TextureUsageFlags.Sampler!"); - } - } - private void AssertNonEmptyCopy(uint dataLengthInBytes) { if (dataLengthInBytes == 0) @@ -1788,14 +1392,6 @@ public class CommandBuffer } } - private void AssertInRenderPass(string message) - { - if (!renderPassActive) - { - throw new System.InvalidOperationException(message); - } - } - private void AssertInCopyPass(string message) { if (!copyPassActive) diff --git a/src/Graphics/GraphicsDevice.cs b/src/Graphics/GraphicsDevice.cs index 4287b6d..a52f222 100644 --- a/src/Graphics/GraphicsDevice.cs +++ b/src/Graphics/GraphicsDevice.cs @@ -38,8 +38,9 @@ namespace MoonWorks.Graphics public bool IsDisposed { get; private set; } private readonly HashSet resources = new HashSet(); - private FencePool FencePool; private CommandBufferPool CommandBufferPool; + internal RenderPassPool RenderPassPool; + private FencePool FencePool; internal unsafe GraphicsDevice( Span preferredBackends, @@ -149,12 +150,12 @@ namespace MoonWorks.Graphics ) ), DepthStencilState = DepthStencilState.Disable, - VertexShaderInfo = GraphicsShaderInfo.Create( + VertexShaderResourceInfo = GraphicsShaderInfo.Create( fullscreenVertShader, "main", 0 ), - FragmentShaderInfo = GraphicsShaderInfo.Create( + FragmentShaderResourceInfo = GraphicsShaderInfo.Create( videoFragShader, "main", 3 @@ -177,12 +178,12 @@ namespace MoonWorks.Graphics ) ), DepthStencilState = DepthStencilState.Disable, - VertexShaderInfo = GraphicsShaderInfo.Create( + VertexShaderResourceInfo = GraphicsShaderInfo.Create( fullscreenVertShader, "main", 0 ), - FragmentShaderInfo = GraphicsShaderInfo.Create( + FragmentShaderResourceInfo = GraphicsShaderInfo.Create( blitFragShader, "main", 1 diff --git a/src/Graphics/RenderPass.cs b/src/Graphics/RenderPass.cs index ee1a8a2..faa8cb5 100644 --- a/src/Graphics/RenderPass.cs +++ b/src/Graphics/RenderPass.cs @@ -13,16 +13,17 @@ public class RenderPass #if DEBUG internal bool active; + internal uint colorAttachmentCount; + internal SampleCount colorAttachmentSampleCount; + internal TextureFormat colorFormatOne; + internal TextureFormat colorFormatTwo; + internal TextureFormat colorFormatThree; + internal TextureFormat colorFormatFour; + internal bool hasDepthStencilAttachment; + internal SampleCount depthStencilAttachmentSampleCount; + internal TextureFormat depthStencilFormat; + GraphicsPipeline currentGraphicsPipeline; - uint colorAttachmentCount; - SampleCount colorAttachmentSampleCount; - TextureFormat colorFormatOne; - TextureFormat colorFormatTwo; - TextureFormat colorFormatThree; - TextureFormat colorFormatFour; - bool hasDepthStencilAttachment; - SampleCount depthStencilAttachmentSampleCount; - TextureFormat depthStencilFormat; #endif internal void SetHandle(nint handle) @@ -79,7 +80,7 @@ public class RenderPass SDL_Gpu.SDL_GpuSetViewport( Handle, - viewport.ToRefresh() + viewport.ToSDL() ); } @@ -99,7 +100,7 @@ public class RenderPass SDL_Gpu.SDL_GpuSetScissor( Handle, - scissor.ToRefresh() + scissor.ToSDL() ); } @@ -108,7 +109,7 @@ public class RenderPass /// /// Buffer to bind and associated offset. /// The index of the first vertex input binding whose state is updated by the command. - public unsafe void BindVertexBuffers( + public unsafe void BindVertexBuffer( in BufferBinding bufferBinding, uint firstBinding = 0 ) { @@ -116,137 +117,16 @@ public class RenderPass AssertGraphicsPipelineBound(); #endif - var bindingArray = stackalloc SDL_Gpu.BufferBinding[1]; - bindingArray[0] = bufferBinding.ToRefresh(); + var sdlBufferBinding = bufferBinding.ToSDL(); SDL_Gpu.SDL_GpuBindVertexBuffers( Handle, firstBinding, - bindingArray, + &sdlBufferBinding, 1 ); } - /// - /// Binds vertex buffers to be used by subsequent draw calls. - /// - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// The index of the first vertex input binding whose state is updated by the command. - public unsafe void BindVertexBuffers( - in BufferBinding bufferBindingOne, - in BufferBinding bufferBindingTwo, - uint firstBinding = 0 - ) { -#if DEBUG - AssertGraphicsPipelineBound(); -#endif - - var bindingArray = stackalloc SDL_Gpu.BufferBinding[2]; - bindingArray[0] = bufferBindingOne.ToRefresh(); - bindingArray[1] = bufferBindingTwo.ToRefresh(); - - SDL_Gpu.SDL_GpuBindVertexBuffers( - Handle, - firstBinding, - bindingArray, - 2 - ); - } - - /// - /// Binds vertex buffers to be used by subsequent draw calls. - /// - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// The index of the first vertex input binding whose state is updated by the command. - public unsafe void BindVertexBuffers( - in BufferBinding bufferBindingOne, - in BufferBinding bufferBindingTwo, - in BufferBinding bufferBindingThree, - uint firstBinding = 0 - ) { -#if DEBUG - AssertGraphicsPipelineBound(); -#endif - - var bindingArray = stackalloc SDL_Gpu.BufferBinding[3]; - bindingArray[0] = bufferBindingOne.ToRefresh(); - bindingArray[1] = bufferBindingTwo.ToRefresh(); - bindingArray[2] = bufferBindingThree.ToRefresh(); - - SDL_Gpu.SDL_GpuBindVertexBuffers( - Handle, - firstBinding, - bindingArray, - 3 - ); - } - - /// - /// Binds vertex buffers to be used by subsequent draw calls. - /// - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// Buffer to bind and associated offset. - /// The index of the first vertex input binding whose state is updated by the command. - public unsafe void BindVertexBuffers( - in BufferBinding bufferBindingOne, - in BufferBinding bufferBindingTwo, - in BufferBinding bufferBindingThree, - in BufferBinding bufferBindingFour, - uint firstBinding = 0 - ) { -#if DEBUG - AssertGraphicsPipelineBound(); -#endif - - var bindingArray = stackalloc SDL_Gpu.BufferBinding[4]; - bindingArray[0] = bufferBindingOne.ToRefresh(); - bindingArray[1] = bufferBindingTwo.ToRefresh(); - bindingArray[2] = bufferBindingThree.ToRefresh(); - bindingArray[3] = bufferBindingFour.ToRefresh(); - - SDL_Gpu.SDL_GpuBindVertexBuffers( - Handle, - firstBinding, - bindingArray, - 4 - ); - } - - /// - /// Binds vertex buffers to be used by subsequent draw calls. - /// - /// Spawn of buffers to bind and their associated offsets. - /// The index of the first vertex input binding whose state is updated by the command. - public unsafe void BindVertexBuffers( - in Span bufferBindings, - uint firstBinding = 0 - ) { -#if DEBUG - AssertGraphicsPipelineBound(); -#endif - - SDL_Gpu.BufferBinding* bufferBindingsArray = (SDL_Gpu.BufferBinding*) NativeMemory.Alloc((nuint) (Marshal.SizeOf() * bufferBindings.Length)); - - for (var i = 0; i < bufferBindings.Length; i += 1) - { - bufferBindingsArray[i] = bufferBindings[i].ToRefresh(); - } - - SDL_Gpu.SDL_GpuBindVertexBuffers( - Handle, - firstBinding, - bufferBindingsArray, - (uint) bufferBindings.Length - ); - - NativeMemory.Free(bufferBindingsArray); - } - /// /// Binds an index buffer to be used by subsequent draw calls. /// @@ -264,7 +144,7 @@ public class RenderPass SDL_Gpu.SDL_GpuBindIndexBuffer( Handle, - bufferBinding.ToRefresh(), + bufferBinding.ToSDL(), (SDL_Gpu.IndexElementSize) indexElementSize ); } @@ -283,104 +163,280 @@ public class RenderPass AssertTextureHasSamplerFlag(textureSamplerBinding.Texture); #endif - var bindingArray = stackalloc SDL_Gpu.TextureSamplerBinding[1]; - bindingArray[0] = textureSamplerBinding.ToSDL(); + var sdlTextureSamplerBinding = textureSamplerBinding.ToSDL(); SDL_Gpu.SDL_GpuBindVertexSamplers( Handle, slot, - bindingArray, + &sdlTextureSamplerBinding, 1 ); } - public unsafe void BindVertexSamplers( - in Span textureSamplerBindings, - uint firstSlot = 0 - ) { -#if DEBUG - AssertGraphicsPipelineBound(); - - for (var i = 0; i < textureSamplerBindings.Length; i += 1) - { - AssertTextureSamplerBindingNonNull(textureSamplerBindings[i]); - AssertTextureHasSamplerFlag(textureSamplerBindings[i].Texture); - } -#endif - - SDL_Gpu.TextureSamplerBinding* samplerBindingsArray = - (SDL_Gpu.TextureSamplerBinding*) NativeMemory.Alloc( - (nuint) (Marshal.SizeOf() * textureSamplerBindings.Length) - ); - - for (var i = 0; i < textureSamplerBindings.Length; i += 1) - { - samplerBindingsArray[i] = textureSamplerBindings[i].ToSDL(); - } - - SDL_Gpu.SDL_GpuBindVertexSamplers( - Handle, - firstSlot, - samplerBindingsArray, - (uint) textureSamplerBindings.Length - ); - - NativeMemory.Free(samplerBindingsArray); - } - public unsafe void BindVertexStorageTexture( - in TextureSlice storageTextureSlice, + in TextureSlice textureSlice, uint slot = 0 ) { #if DEBUG AssertGraphicsPipelineBound(); - AssertTextureNonNull(storageTextureSlice.Texture); - AssertTextureHasGraphicsStorageFlag(storageTextureSlice.Texture); + AssertTextureNonNull(textureSlice.Texture); + AssertTextureHasGraphicsStorageFlag(textureSlice.Texture); #endif - var sliceArray = stackalloc SDL_Gpu.TextureSlice[1]; - sliceArray[0] = storageTextureSlice.ToSDL(); + var sdlTextureSlice = textureSlice.ToSDL(); SDL_Gpu.SDL_GpuBindVertexStorageTextures( Handle, slot, - sliceArray, + &sdlTextureSlice, 1 ); } - public unsafe void BindVertexStorageTextures( - in Span storageTextureSlices, - uint firstSlot = 0 + public unsafe void BindVertexStorageBuffer( + GpuBuffer buffer, + uint slot = 0 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertBufferNonNull(buffer); + AssertBufferHasGraphicsStorageFlag(buffer); +#endif + + var bufferHandle = buffer.Handle; + + SDL_Gpu.SDL_GpuBindVertexStorageBuffers( + Handle, + slot, + &bufferHandle, + 1 + ); + } + + public unsafe void BindFragmentSamplers( + in TextureSamplerBinding textureSamplerBinding, + uint slot = 0 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertTextureSamplerBindingNonNull(textureSamplerBinding); + AssertTextureHasSamplerFlag(textureSamplerBinding.Texture); +#endif + + var sdlTextureSamplerBinding = textureSamplerBinding.ToSDL(); + + SDL_Gpu.SDL_GpuBindFragmentSamplers( + Handle, + slot, + &sdlTextureSamplerBinding, + 1 + ); + } + + public unsafe void BindFragmentStorageTexture( + in TextureSlice textureSlice, + uint slot = 0 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertTextureNonNull(textureSlice.Texture); + AssertTextureHasGraphicsStorageFlag(textureSlice.Texture); +#endif + + var sdlTextureSlice = textureSlice.ToSDL(); + + SDL_Gpu.SDL_GpuBindFragmentStorageTextures( + Handle, + slot, + &sdlTextureSlice, + 1 + ); + } + + public unsafe void BindFragmentStorageBuffer( + GpuBuffer buffer, + uint slot = 0 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + AssertBufferNonNull(buffer); + AssertBufferHasGraphicsStorageFlag(buffer); +#endif + + var bufferHandle = buffer.Handle; + + SDL_Gpu.SDL_GpuBindFragmentStorageBuffers( + Handle, + slot, + &bufferHandle, + 1 + ); + } + + public unsafe void PushVertexUniformData( + void* uniformsPtr, + uint size, + uint slot = 0 ) { #if DEBUG AssertGraphicsPipelineBound(); - for (var i = 0; i < storageTextureSlices.Length; i += 1) + if (slot >= currentGraphicsPipeline.VertexShaderResourceInfo.UniformBufferCount) { - AssertTextureNonNull(storageTextureSlices[i].Texture); - AssertTextureHasGraphicsStorageFlag(storageTextureSlices[i].Texture); + throw new System.ArgumentException($"Slot {slot} given, but {currentGraphicsPipeline.VertexShaderResourceInfo.UniformBufferCount} uniform buffers are used on the shader!"); } #endif - SDL_Gpu.TextureSlice* sliceArray = - (SDL_Gpu.TextureSlice*) NativeMemory.Alloc( - (nuint) (Marshal.SizeOf() * storageTextureSlices.Length) - ); - - for (var i = 0; i < storageTextureSlices.Length; i += 1) - { - sliceArray[i] = storageTextureSlices[i].ToSDL(); - } - - SDL_Gpu.SDL_GpuBindVertexStorageTextures( + SDL_Gpu.SDL_GpuPushVertexUniformData( Handle, - firstSlot, - sliceArray, - (uint) storageTextureSlices.Length + slot, + (nint) uniformsPtr, + size ); + } - NativeMemory.Free(sliceArray); + public unsafe void PushVertexUniformData( + in T uniforms + ) where T : unmanaged + { + fixed (T* uniformsPtr = &uniforms) + { + PushVertexUniformData(uniformsPtr, (uint) Marshal.SizeOf()); + } + } + + public unsafe void PushFragmentUniformData( + void* uniformsPtr, + uint size, + uint slot = 0 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); + + if (slot >= currentGraphicsPipeline.FragmentShaderResourceInfo.UniformBufferCount) + { + throw new System.ArgumentException($"Slot {slot} given, but {currentGraphicsPipeline.FragmentShaderResourceInfo.UniformBufferCount} uniform buffers are used on the shader!"); + } +#endif + + SDL_Gpu.SDL_GpuPushFragmentUniformData( + Handle, + slot, + (nint) uniformsPtr, + size + ); + } + + public unsafe void PushFragmentUniformData( + in T uniforms + ) where T : unmanaged + { + fixed (T* uniformsPtr = &uniforms) + { + PushFragmentUniformData(uniformsPtr, (uint) Marshal.SizeOf()); + } + } + + /// + /// Draws using a vertex buffer and an index buffer, and an optional instance count. + /// + /// The starting index offset for the vertex buffer. + /// The starting index offset for the index buffer. + /// The number of primitives to draw. + /// The number of instances to draw. + public void DrawIndexedPrimitives( + uint baseVertex, + uint startIndex, + uint primitiveCount, + uint instanceCount = 1 + ) { +#if DEBUG + AssertGraphicsPipelineBound(); +#endif + + SDL_Gpu.SDL_GpuDrawIndexedPrimitives( + Handle, + baseVertex, + startIndex, + primitiveCount, + instanceCount + ); + } + + /// + /// Draws using a vertex buffer and an index buffer. + /// + /// The starting index offset for the vertex buffer. + /// The starting index offset for the index buffer. + /// The number of primitives to draw. + public void DrawPrimitives( + uint vertexStart, + uint primitiveCount + ) + { +#if DEBUG + AssertGraphicsPipelineBound(); +#endif + + SDL_Gpu.SDL_GpuDrawPrimitives( + Handle, + vertexStart, + primitiveCount + ); + } + + /// + /// Similar to DrawPrimitives, but parameters are set from a buffer. + /// The buffer must have the Indirect usage flag set. + /// + /// The draw parameters buffer. + /// The offset to start reading from the draw parameters buffer. + /// The number of draw parameter sets that should be read from the buffer. + /// The byte stride between sets of draw parameters. + public void DrawPrimitivesIndirect( + GpuBuffer buffer, + uint offsetInBytes, + uint drawCount, + uint stride + ) { +#if DEBUG + AssertGraphicsPipelineBound(); +#endif + + SDL_Gpu.SDL_GpuDrawPrimitivesIndirect( + Handle, + buffer.Handle, + offsetInBytes, + drawCount, + stride + ); + } + + /// + /// Similar to DrawIndexedPrimitives, but parameters are set from a buffer. + /// The buffer must have the Indirect usage flag set. + /// + /// The draw parameters buffer. + /// The offset to start reading from the draw parameters buffer. + /// The number of draw parameter sets that should be read from the buffer. + /// The byte stride between sets of draw parameters. + public void DrawIndexedPrimitivesIndirect( + GpuBuffer buffer, + uint offsetInBytes, + uint drawCount, + uint stride + ) { +#if DEBUG + AssertGraphicsPipelineBound(); +#endif + + SDL_Gpu.SDL_GpuDrawIndexedPrimitivesIndirect( + Handle, + buffer.Handle, + offsetInBytes, + drawCount, + stride + ); } #if DEBUG @@ -481,5 +537,21 @@ public class RenderPass throw new System.ArgumentException("The bound Texture's UsageFlags must include TextureUsageFlags.GraphicsStorage!"); } } + + private void AssertBufferNonNull(GpuBuffer buffer) + { + if (buffer == null || buffer.Handle == IntPtr.Zero) + { + throw new System.NullReferenceException("Buffer must not be null!"); + } + } + + private void AssertBufferHasGraphicsStorageFlag(GpuBuffer buffer) + { + if ((buffer.UsageFlags & BufferUsageFlags.GraphicsStorage) == 0) + { + throw new System.ArgumentException("The bound Buffer's UsageFlags must include BufferUsageFlag.GraphicsStorage!"); + } + } #endif } diff --git a/src/Graphics/RenderPassPool.cs b/src/Graphics/RenderPassPool.cs new file mode 100644 index 0000000..d0bf0f3 --- /dev/null +++ b/src/Graphics/RenderPassPool.cs @@ -0,0 +1,26 @@ +using System.Collections.Concurrent; + +namespace MoonWorks.Graphics +{ + internal class RenderPassPool + { + private ConcurrentQueue RenderPasses = new ConcurrentQueue(); + + public RenderPass Obtain() + { + if (RenderPasses.TryDequeue(out var renderPass)) + { + return renderPass; + } + else + { + return new RenderPass(); + } + } + + public void Return(RenderPass renderPass) + { + RenderPasses.Enqueue(renderPass); + } + } +} diff --git a/src/Graphics/Resources/GpuBuffer.cs b/src/Graphics/Resources/GpuBuffer.cs index be07dd0..3bc0c3d 100644 --- a/src/Graphics/Resources/GpuBuffer.cs +++ b/src/Graphics/Resources/GpuBuffer.cs @@ -1,86 +1,88 @@ using System; using System.Runtime.InteropServices; -using RefreshCS; +using SDL2_gpuCS; -namespace MoonWorks.Graphics +namespace MoonWorks.Graphics; + +/// +/// GpuBuffers are generic data containers that can be used by the GPU. +/// +public class GpuBuffer : SDL_GpuResource { + protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseBuffer; + + public BufferUsageFlags UsageFlags { get; } + /// - /// GpuBuffers are generic data containers that can be used by the GPU. + /// Size in bytes. /// - public class GpuBuffer : SDL_GpuResource + public uint Size { get; } + + private string name; + public string Name { - protected override Action ReleaseFunction => Refresh.Refresh_QueueDestroyGpuBuffer; + get => name; - /// - /// Size in bytes. - /// - public uint Size { get; } - - private string name; - public string Name + set { - get => name; - - set + if (Device.DebugMode) { - if (Device.DebugMode) - { - Refresh.Refresh_SetGpuBufferName( - Device.Handle, - Handle, - value - ); - } - - name = value; + SDL_Gpu.SDL_GpuSetBufferName( + Device.Handle, + Handle, + value + ); } - } - /// - /// Creates a buffer of appropriate size given a type and element count. - /// - /// The type that the buffer will contain. - /// The GraphicsDevice. - /// Specifies how the buffer will be used. - /// How many elements of type T the buffer will contain. - /// - public unsafe static GpuBuffer Create( - GraphicsDevice device, - BufferUsageFlags usageFlags, - uint elementCount - ) where T : unmanaged - { - return new GpuBuffer( - device, - usageFlags, - (uint) Marshal.SizeOf() * elementCount - ); - } - - /// - /// Creates a buffer. - /// - /// An initialized GraphicsDevice. - /// Specifies how the buffer will be used. - /// The length of the array. Cannot be resized. - public GpuBuffer( - GraphicsDevice device, - BufferUsageFlags usageFlags, - uint sizeInBytes - ) : base(device) - { - Handle = Refresh.Refresh_CreateGpuBuffer( - device.Handle, - (Refresh.BufferUsageFlags) usageFlags, - sizeInBytes - ); - Size = sizeInBytes; - name = ""; - } - - public static implicit operator BufferBinding(GpuBuffer b) - { - return new BufferBinding(b, 0); + name = value; } } + + /// + /// Creates a buffer of appropriate size given a type and element count. + /// + /// The type that the buffer will contain. + /// The GraphicsDevice. + /// Specifies how the buffer will be used. + /// How many elements of type T the buffer will contain. + /// + public unsafe static GpuBuffer Create( + GraphicsDevice device, + BufferUsageFlags usageFlags, + uint elementCount + ) where T : unmanaged + { + return new GpuBuffer( + device, + usageFlags, + (uint) Marshal.SizeOf() * elementCount + ); + } + + /// + /// Creates a buffer. + /// + /// An initialized GraphicsDevice. + /// Specifies how the buffer will be used. + /// The length of the array. Cannot be resized. + public GpuBuffer( + GraphicsDevice device, + BufferUsageFlags usageFlags, + uint sizeInBytes + ) : base(device) + { + Handle = SDL_Gpu.SDL_GpuCreateBuffer( + device.Handle, + (SDL_Gpu.BufferUsageFlags) usageFlags, + sizeInBytes + ); + UsageFlags = usageFlags; + Size = sizeInBytes; + name = ""; + } + + public static implicit operator BufferBinding(GpuBuffer b) + { + return new BufferBinding(b, 0); + } } diff --git a/src/Graphics/Resources/GraphicsPipeline.cs b/src/Graphics/Resources/GraphicsPipeline.cs index e69889c..fe0035f 100644 --- a/src/Graphics/Resources/GraphicsPipeline.cs +++ b/src/Graphics/Resources/GraphicsPipeline.cs @@ -1,6 +1,6 @@ using System; using System.Runtime.InteropServices; -using RefreshCS; +using SDL2_gpuCS; namespace MoonWorks.Graphics { @@ -10,10 +10,10 @@ namespace MoonWorks.Graphics /// public class GraphicsPipeline : SDL_GpuResource { - protected override Action ReleaseFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline; + protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseGraphicsPipeline; - public GraphicsShaderInfo VertexShaderInfo { get; } - public GraphicsShaderInfo FragmentShaderInfo { get; } + public GraphicsPipelineResourceInfo VertexShaderResourceInfo { get; } + public GraphicsPipelineResourceInfo FragmentShaderResourceInfo { get; } public SampleCount SampleCount { get; } #if DEBUG @@ -25,103 +25,78 @@ namespace MoonWorks.Graphics in GraphicsPipelineCreateInfo graphicsPipelineCreateInfo ) : base(device) { - DepthStencilState depthStencilState = graphicsPipelineCreateInfo.DepthStencilState; - GraphicsShaderInfo vertexShaderInfo = graphicsPipelineCreateInfo.VertexShaderInfo; - GraphicsShaderInfo fragmentShaderInfo = graphicsPipelineCreateInfo.FragmentShaderInfo; - MultisampleState multisampleState = graphicsPipelineCreateInfo.MultisampleState; - RasterizerState rasterizerState = graphicsPipelineCreateInfo.RasterizerState; - PrimitiveType primitiveType = graphicsPipelineCreateInfo.PrimitiveType; - VertexInputState vertexInputState = graphicsPipelineCreateInfo.VertexInputState; - GraphicsPipelineAttachmentInfo attachmentInfo = graphicsPipelineCreateInfo.AttachmentInfo; - BlendConstants blendConstants = graphicsPipelineCreateInfo.BlendConstants; + SDL_Gpu.GraphicsPipelineCreateInfo sdlGraphicsPipelineCreateInfo; - var vertexAttributesHandle = GCHandle.Alloc( - vertexInputState.VertexAttributes, - GCHandleType.Pinned - ); - var vertexBindingsHandle = GCHandle.Alloc( - vertexInputState.VertexBindings, - GCHandleType.Pinned + var vertexAttributes = (SDL_Gpu.VertexAttribute*) NativeMemory.Alloc( + (nuint) (graphicsPipelineCreateInfo.VertexInputState.VertexAttributes.Length * Marshal.SizeOf()) ); - var colorAttachmentDescriptions = stackalloc Refresh.ColorAttachmentDescription[ - (int) attachmentInfo.ColorAttachmentDescriptions.Length - ]; - - for (var i = 0; i < attachmentInfo.ColorAttachmentDescriptions.Length; i += 1) + for (var i = 0; i < graphicsPipelineCreateInfo.VertexInputState.VertexAttributes.Length; i += 1) { - colorAttachmentDescriptions[i].format = (Refresh.TextureFormat) attachmentInfo.ColorAttachmentDescriptions[i].Format; - colorAttachmentDescriptions[i].blendState = attachmentInfo.ColorAttachmentDescriptions[i].BlendState.ToRefresh(); + vertexAttributes[i] = graphicsPipelineCreateInfo.VertexInputState.VertexAttributes[i].ToSDL(); } - Refresh.GraphicsPipelineCreateInfo refreshGraphicsPipelineCreateInfo; + var vertexBindings = (SDL_Gpu.VertexBinding*) NativeMemory.Alloc( + (nuint) (graphicsPipelineCreateInfo.VertexInputState.VertexBindings.Length * Marshal.SizeOf()) + ); - refreshGraphicsPipelineCreateInfo.blendConstants[0] = blendConstants.R; - refreshGraphicsPipelineCreateInfo.blendConstants[1] = blendConstants.G; - refreshGraphicsPipelineCreateInfo.blendConstants[2] = blendConstants.B; - refreshGraphicsPipelineCreateInfo.blendConstants[3] = blendConstants.A; + for (var i = 0; i < graphicsPipelineCreateInfo.VertexInputState.VertexBindings.Length; i += 1) + { + vertexBindings[i] = graphicsPipelineCreateInfo.VertexInputState.VertexBindings[i].ToSDL(); + } - refreshGraphicsPipelineCreateInfo.depthStencilState.backStencilState = depthStencilState.BackStencilState.ToRefresh(); - refreshGraphicsPipelineCreateInfo.depthStencilState.frontStencilState = depthStencilState.FrontStencilState.ToRefresh(); - refreshGraphicsPipelineCreateInfo.depthStencilState.compareMask = depthStencilState.CompareMask; - refreshGraphicsPipelineCreateInfo.depthStencilState.writeMask = depthStencilState.WriteMask; - refreshGraphicsPipelineCreateInfo.depthStencilState.reference = depthStencilState.Reference; - refreshGraphicsPipelineCreateInfo.depthStencilState.compareOp = (Refresh.CompareOp) depthStencilState.CompareOp; - refreshGraphicsPipelineCreateInfo.depthStencilState.depthBoundsTestEnable = Conversions.BoolToByte(depthStencilState.DepthBoundsTestEnable); - refreshGraphicsPipelineCreateInfo.depthStencilState.depthTestEnable = Conversions.BoolToByte(depthStencilState.DepthTestEnable); - refreshGraphicsPipelineCreateInfo.depthStencilState.depthWriteEnable = Conversions.BoolToByte(depthStencilState.DepthWriteEnable); - refreshGraphicsPipelineCreateInfo.depthStencilState.maxDepthBounds = depthStencilState.MaxDepthBounds; - refreshGraphicsPipelineCreateInfo.depthStencilState.minDepthBounds = depthStencilState.MinDepthBounds; - refreshGraphicsPipelineCreateInfo.depthStencilState.stencilTestEnable = Conversions.BoolToByte(depthStencilState.StencilTestEnable); + var colorAttachmentDescriptions = stackalloc SDL_Gpu.ColorAttachmentDescription[ + graphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions.Length + ]; - refreshGraphicsPipelineCreateInfo.vertexShaderInfo.entryPointName = vertexShaderInfo.EntryPointName; - refreshGraphicsPipelineCreateInfo.vertexShaderInfo.shaderModule = vertexShaderInfo.ShaderModule.Handle; - refreshGraphicsPipelineCreateInfo.vertexShaderInfo.uniformBufferSize = vertexShaderInfo.UniformBufferSize; - refreshGraphicsPipelineCreateInfo.vertexShaderInfo.samplerBindingCount = vertexShaderInfo.SamplerBindingCount; + for (var i = 0; i < graphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions.Length; i += 1) + { + colorAttachmentDescriptions[i].Format = (SDL_Gpu.TextureFormat) graphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions[i].Format; + colorAttachmentDescriptions[i].BlendState = graphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions[i].BlendState.ToSDL(); + } - refreshGraphicsPipelineCreateInfo.fragmentShaderInfo.entryPointName = fragmentShaderInfo.EntryPointName; - refreshGraphicsPipelineCreateInfo.fragmentShaderInfo.shaderModule = fragmentShaderInfo.ShaderModule.Handle; - refreshGraphicsPipelineCreateInfo.fragmentShaderInfo.uniformBufferSize = fragmentShaderInfo.UniformBufferSize; - refreshGraphicsPipelineCreateInfo.fragmentShaderInfo.samplerBindingCount = fragmentShaderInfo.SamplerBindingCount; + sdlGraphicsPipelineCreateInfo.VertexShader = graphicsPipelineCreateInfo.VertexShader.Handle; + sdlGraphicsPipelineCreateInfo.FragmentShader = graphicsPipelineCreateInfo.FragmentShader.Handle; - refreshGraphicsPipelineCreateInfo.multisampleState.multisampleCount = (Refresh.SampleCount) multisampleState.MultisampleCount; - refreshGraphicsPipelineCreateInfo.multisampleState.sampleMask = multisampleState.SampleMask; + sdlGraphicsPipelineCreateInfo.VertexInputState.VertexAttributes = vertexAttributes; + sdlGraphicsPipelineCreateInfo.VertexInputState.VertexAttributeCount = (uint) graphicsPipelineCreateInfo.VertexInputState.VertexAttributes.Length; + sdlGraphicsPipelineCreateInfo.VertexInputState.VertexBindings = vertexBindings; + sdlGraphicsPipelineCreateInfo.VertexInputState.VertexBindingCount = (uint) graphicsPipelineCreateInfo.VertexInputState.VertexBindings.Length; - refreshGraphicsPipelineCreateInfo.rasterizerState.cullMode = (Refresh.CullMode) rasterizerState.CullMode; - refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasClamp = rasterizerState.DepthBiasClamp; - refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasConstantFactor = rasterizerState.DepthBiasConstantFactor; - refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasEnable = Conversions.BoolToByte(rasterizerState.DepthBiasEnable); - refreshGraphicsPipelineCreateInfo.rasterizerState.depthBiasSlopeFactor = rasterizerState.DepthBiasSlopeFactor; - refreshGraphicsPipelineCreateInfo.rasterizerState.fillMode = (Refresh.FillMode) rasterizerState.FillMode; - refreshGraphicsPipelineCreateInfo.rasterizerState.frontFace = (Refresh.FrontFace) rasterizerState.FrontFace; + sdlGraphicsPipelineCreateInfo.PrimitiveType = (SDL_Gpu.PrimitiveType) graphicsPipelineCreateInfo.PrimitiveType; - refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributes = vertexAttributesHandle.AddrOfPinnedObject(); - refreshGraphicsPipelineCreateInfo.vertexInputState.vertexAttributeCount = (uint) vertexInputState.VertexAttributes.Length; - refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindings = vertexBindingsHandle.AddrOfPinnedObject(); - refreshGraphicsPipelineCreateInfo.vertexInputState.vertexBindingCount = (uint) vertexInputState.VertexBindings.Length; + sdlGraphicsPipelineCreateInfo.RasterizerState = graphicsPipelineCreateInfo.RasterizerState.ToSDL(); + sdlGraphicsPipelineCreateInfo.MultisampleState = graphicsPipelineCreateInfo.MultisampleState.ToSDL(); + sdlGraphicsPipelineCreateInfo.DepthStencilState = graphicsPipelineCreateInfo.DepthStencilState.ToSDL(); - refreshGraphicsPipelineCreateInfo.primitiveType = (Refresh.PrimitiveType) primitiveType; + sdlGraphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentCount = (uint) graphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions.Length; + sdlGraphicsPipelineCreateInfo.AttachmentInfo.ColorAttachmentDescriptions = colorAttachmentDescriptions; + sdlGraphicsPipelineCreateInfo.AttachmentInfo.DepthStencilFormat = (SDL_Gpu.TextureFormat) graphicsPipelineCreateInfo.AttachmentInfo.DepthStencilFormat; + sdlGraphicsPipelineCreateInfo.AttachmentInfo.HasDepthStencilAttachment = Conversions.BoolToInt(graphicsPipelineCreateInfo.AttachmentInfo.HasDepthStencilAttachment); - refreshGraphicsPipelineCreateInfo.attachmentInfo.colorAttachmentCount = (uint) attachmentInfo.ColorAttachmentDescriptions.Length; - refreshGraphicsPipelineCreateInfo.attachmentInfo.colorAttachmentDescriptions = (IntPtr) colorAttachmentDescriptions; - refreshGraphicsPipelineCreateInfo.attachmentInfo.depthStencilFormat = (Refresh.TextureFormat) attachmentInfo.DepthStencilFormat; - refreshGraphicsPipelineCreateInfo.attachmentInfo.hasDepthStencilAttachment = Conversions.BoolToByte(attachmentInfo.HasDepthStencilAttachment); + sdlGraphicsPipelineCreateInfo.VertexResourceInfo = graphicsPipelineCreateInfo.VertexShaderResourceInfo.ToSDL(); + sdlGraphicsPipelineCreateInfo.FragmentResourceInfo = graphicsPipelineCreateInfo.FragmentShaderResourceInfo.ToSDL(); - Handle = Refresh.Refresh_CreateGraphicsPipeline(device.Handle, refreshGraphicsPipelineCreateInfo); + sdlGraphicsPipelineCreateInfo.BlendConstants[0] = graphicsPipelineCreateInfo.BlendConstants.R; + sdlGraphicsPipelineCreateInfo.BlendConstants[1] = graphicsPipelineCreateInfo.BlendConstants.G; + sdlGraphicsPipelineCreateInfo.BlendConstants[2] = graphicsPipelineCreateInfo.BlendConstants.B; + sdlGraphicsPipelineCreateInfo.BlendConstants[3] = graphicsPipelineCreateInfo.BlendConstants.A; + + Handle = SDL_Gpu.SDL_GpuCreateGraphicsPipeline(device.Handle, sdlGraphicsPipelineCreateInfo); if (Handle == IntPtr.Zero) { throw new Exception("Could not create graphics pipeline!"); } - vertexAttributesHandle.Free(); - vertexBindingsHandle.Free(); + NativeMemory.Free(vertexAttributes); + NativeMemory.Free(vertexBindings); - VertexShaderInfo = vertexShaderInfo; - FragmentShaderInfo = fragmentShaderInfo; - SampleCount = multisampleState.MultisampleCount; + VertexShaderResourceInfo = graphicsPipelineCreateInfo.VertexShaderResourceInfo; + FragmentShaderResourceInfo = graphicsPipelineCreateInfo.FragmentShaderResourceInfo; + SampleCount = graphicsPipelineCreateInfo.MultisampleState.MultisampleCount; #if DEBUG - AttachmentInfo = attachmentInfo; + AttachmentInfo = graphicsPipelineCreateInfo.AttachmentInfo; #endif } } diff --git a/src/Graphics/Resources/Texture.cs b/src/Graphics/Resources/Texture.cs index d6a8435..f601e73 100644 --- a/src/Graphics/Resources/Texture.cs +++ b/src/Graphics/Resources/Texture.cs @@ -1,6 +1,6 @@ using System; using System.IO; -using RefreshCS; +using SDL2_gpuCS; namespace MoonWorks.Graphics { @@ -29,7 +29,7 @@ namespace MoonWorks.Graphics { if (Device.DebugMode) { - Refresh.Refresh_SetTextureName( + SDL_Gpu.SDL_GpuSetTextureName( Device.Handle, Handle, value @@ -41,7 +41,7 @@ namespace MoonWorks.Graphics } // FIXME: this allocates a delegate instance - protected override Action ReleaseFunction => Refresh.Refresh_QueueDestroyTexture; + protected override Action ReleaseFunction => SDL_Gpu.SDL_GpuReleaseTexture; /// /// Creates a 2D texture. @@ -179,9 +179,9 @@ namespace MoonWorks.Graphics in TextureCreateInfo textureCreateInfo ) : base(device) { - Handle = Refresh.Refresh_CreateTexture( + Handle = SDL_Gpu.SDL_GpuCreateTexture( device.Handle, - textureCreateInfo.ToRefreshTextureCreateInfo() + textureCreateInfo.ToSDL() ); Format = textureCreateInfo.Format; diff --git a/src/Graphics/SDL_GpuTypes.cs b/src/Graphics/SDL_GpuTypes.cs index 3cd3e02..34eac9d 100644 --- a/src/Graphics/SDL_GpuTypes.cs +++ b/src/Graphics/SDL_GpuTypes.cs @@ -36,52 +36,52 @@ public enum IndexElementSize public enum TextureFormat { -/* Unsigned Normalized Float Color Formats */ -R8G8B8A8, -B8G8R8A8, -R5G6B5, -A1R5G5B5, -B4G4R4A4, -A2R10G10B10, -A2B10G10R10, -R16G16, -R16G16B16A16, -R8, -A8, -/* Compressed Unsigned Normalized Float Color Formats */ -BC1, -BC2, -BC3, -BC7, -/* Signed Normalized Float Color Formats */ -R8G8_SNORM, -R8G8B8A8_SNORM, -/* Signed Float Color Formats */ -R16_SFLOAT, -R16G16_SFLOAT, -R16G16B16A16_SFLOAT, -R32_SFLOAT, -R32G32_SFLOAT, -R32G32B32A32_SFLOAT, -/* Unsigned Integer Color Formats */ -R8_UINT, -R8G8_UINT, -R8G8B8A8_UINT, -R16_UINT, -R16G16_UINT, -R16G16B16A16_UINT, -/* SRGB Color Formats */ -R8G8B8A8_SRGB, -B8G8R8A8_SRGB, -/* Compressed SRGB Color Formats */ -BC3_SRGB, -BC7_SRGB, -/* Depth Formats */ -D16_UNORM, -D24_UNORM, -D32_SFLOAT, -D24_UNORM_S8_UINT, -D32_SFLOAT_S8_UINT + /* Unsigned Normalized Float Color Formats */ + R8G8B8A8, + B8G8R8A8, + R5G6B5, + A1R5G5B5, + B4G4R4A4, + A2R10G10B10, + A2B10G10R10, + R16G16, + R16G16B16A16, + R8, + A8, + /* Compressed Unsigned Normalized Float Color Formats */ + BC1, + BC2, + BC3, + BC7, + /* Signed Normalized Float Color Formats */ + R8G8_SNORM, + R8G8B8A8_SNORM, + /* Signed Float Color Formats */ + R16_SFLOAT, + R16G16_SFLOAT, + R16G16B16A16_SFLOAT, + R32_SFLOAT, + R32G32_SFLOAT, + R32G32B32A32_SFLOAT, + /* Unsigned Integer Color Formats */ + R8_UINT, + R8G8_UINT, + R8G8B8A8_UINT, + R16_UINT, + R16G16_UINT, + R16G16B16A16_UINT, + /* SRGB Color Formats */ + R8G8B8A8_SRGB, + B8G8R8A8_SRGB, + /* Compressed SRGB Color Formats */ + BC3_SRGB, + BC7_SRGB, + /* Depth Formats */ + D16_UNORM, + D24_UNORM, + D32_SFLOAT, + D24_UNORM_S8_UINT, + D32_SFLOAT_S8_UINT } [Flags] @@ -251,10 +251,13 @@ public enum BlendFactor [Flags] public enum ColorComponentFlags { + None = 0x0, R = 0x1, G = 0x2, B = 0x4, - A = 0x8 + A = 0x8, + RGB = R | G | B, + RGBA = R | G| B | A } public enum Filter @@ -366,7 +369,7 @@ public struct Rect } // FIXME: can we do an unsafe cast somehow? - public SDL_Gpu.Rect ToRefresh() + public SDL_Gpu.Rect ToSDL() { return new SDL_Gpu.Rect { @@ -448,6 +451,16 @@ public struct VertexBinding Stride = (uint) Marshal.SizeOf() }; } + + public SDL_Gpu.VertexBinding ToSDL() + { + return new SDL_Gpu.VertexBinding + { + Binding = Binding, + Stride = Stride, + InputRate = (SDL_Gpu.VertexInputRate) InputRate + }; + } } [StructLayout(LayoutKind.Sequential)] @@ -457,6 +470,17 @@ public struct VertexAttribute public uint Binding; public VertexElementFormat Format; public uint Offset; + + public SDL_Gpu.VertexAttribute ToSDL() + { + return new SDL_Gpu.VertexAttribute + { + Location = Location, + Binding = Binding, + Format = (SDL_Gpu.VertexElementFormat) Format, + Offset = Offset + }; + } } [StructLayout(LayoutKind.Sequential)] @@ -797,3 +821,39 @@ public readonly record struct BufferImageCopy( }; } } + +public readonly record struct GraphicsPipelineResourceInfo( + uint SamplerCount, + uint StorageBufferCount, + uint StorageTextureCount, + uint UniformBufferCount +) { + public SDL_Gpu.GraphicsPipelineResourceInfo ToSDL() + { + return new SDL_Gpu.GraphicsPipelineResourceInfo + { + SamplerCount = SamplerCount, + StorageBufferCount = StorageBufferCount, + StorageTextureCount = StorageTextureCount, + UniformBufferCount = UniformBufferCount + }; + } +} + +/// +/// All of the information that is used to create a GraphicsPipeline. +/// +public struct GraphicsPipelineCreateInfo +{ + public Shader VertexShader; + public Shader FragmentShader; + public VertexInputState VertexInputState; + public PrimitiveType PrimitiveType; + public RasterizerState RasterizerState; + public MultisampleState MultisampleState; + public DepthStencilState DepthStencilState; + public GraphicsPipelineAttachmentInfo AttachmentInfo; + public GraphicsPipelineResourceInfo VertexShaderResourceInfo; + public GraphicsPipelineResourceInfo FragmentShaderResourceInfo; + public BlendConstants BlendConstants; +} diff --git a/src/Graphics/State/ColorAttachmentBlendState.cs b/src/Graphics/State/ColorAttachmentBlendState.cs index 0f5f610..809c66b 100644 --- a/src/Graphics/State/ColorAttachmentBlendState.cs +++ b/src/Graphics/State/ColorAttachmentBlendState.cs @@ -1,4 +1,4 @@ -using RefreshCS; +using SDL2_gpuCS; namespace MoonWorks.Graphics { @@ -106,18 +106,18 @@ namespace MoonWorks.Graphics ColorWriteMask = ColorComponentFlags.None }; - public Refresh.ColorAttachmentBlendState ToRefresh() + public SDL_Gpu.ColorAttachmentBlendState ToSDL() { - return new Refresh.ColorAttachmentBlendState + return new SDL_Gpu.ColorAttachmentBlendState { - blendEnable = Conversions.BoolToByte(BlendEnable), - alphaBlendOp = (Refresh.BlendOp) AlphaBlendOp, - colorBlendOp = (Refresh.BlendOp) ColorBlendOp, - colorWriteMask = (Refresh.ColorComponentFlags) ColorWriteMask, - destinationAlphaBlendFactor = (Refresh.BlendFactor) DestinationAlphaBlendFactor, - destinationColorBlendFactor = (Refresh.BlendFactor) DestinationColorBlendFactor, - sourceAlphaBlendFactor = (Refresh.BlendFactor) SourceAlphaBlendFactor, - sourceColorBlendFactor = (Refresh.BlendFactor) SourceColorBlendFactor + BlendEnable = Conversions.BoolToInt(BlendEnable), + AlphaBlendOp = (SDL_Gpu.BlendOp) AlphaBlendOp, + ColorBlendOp = (SDL_Gpu.BlendOp) ColorBlendOp, + ColorWriteMask = (SDL_Gpu.ColorComponentFlags) ColorWriteMask, + DestinationAlphaBlendFactor = (SDL_Gpu.BlendFactor) DestinationAlphaBlendFactor, + DestinationColorBlendFactor = (SDL_Gpu.BlendFactor) DestinationColorBlendFactor, + SourceAlphaBlendFactor = (SDL_Gpu.BlendFactor) SourceAlphaBlendFactor, + SourceColorBlendFactor = (SDL_Gpu.BlendFactor) SourceColorBlendFactor }; } } diff --git a/src/Graphics/State/DepthStencilState.cs b/src/Graphics/State/DepthStencilState.cs index 40febd3..7ac2dcd 100644 --- a/src/Graphics/State/DepthStencilState.cs +++ b/src/Graphics/State/DepthStencilState.cs @@ -1,4 +1,6 @@ -namespace MoonWorks.Graphics +using SDL2_gpuCS; + +namespace MoonWorks.Graphics { /// /// Determines how data is written to and read from the depth/stencil buffer. @@ -90,5 +92,24 @@ DepthBoundsTestEnable = false, StencilTestEnable = false }; + + public SDL_Gpu.DepthStencilState ToSDL() + { + return new SDL_Gpu.DepthStencilState + { + DepthTestEnable = Conversions.BoolToInt(DepthTestEnable), + BackStencilState = BackStencilState.ToSDL(), + FrontStencilState = FrontStencilState.ToSDL(), + CompareMask = CompareMask, + WriteMask = WriteMask, + Reference = Reference, + CompareOp = (SDL_Gpu.CompareOp) CompareOp, + DepthBoundsTestEnable = Conversions.BoolToInt(DepthBoundsTestEnable), + DepthWriteEnable = Conversions.BoolToInt(DepthWriteEnable), + MinDepthBounds = MinDepthBounds, + MaxDepthBounds = MaxDepthBounds, + StencilTestEnable = Conversions.BoolToInt(StencilTestEnable) + }; + } } } diff --git a/src/Graphics/State/GraphicsPipelineAttachmentInfo.cs b/src/Graphics/State/GraphicsPipelineAttachmentInfo.cs index a1f6e9c..a906ffc 100644 --- a/src/Graphics/State/GraphicsPipelineAttachmentInfo.cs +++ b/src/Graphics/State/GraphicsPipelineAttachmentInfo.cs @@ -14,7 +14,7 @@ namespace MoonWorks.Graphics ) { ColorAttachmentDescriptions = colorAttachmentDescriptions; HasDepthStencilAttachment = false; - DepthStencilFormat = TextureFormat.D16; + DepthStencilFormat = TextureFormat.D16_UNORM; } public GraphicsPipelineAttachmentInfo( diff --git a/src/Graphics/State/GraphicsPipelineCreateInfo.cs b/src/Graphics/State/GraphicsPipelineCreateInfo.cs deleted file mode 100644 index c46e60c..0000000 --- a/src/Graphics/State/GraphicsPipelineCreateInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace MoonWorks.Graphics -{ - /// - /// All of the information that is used to create a GraphicsPipeline. - /// - public struct GraphicsPipelineCreateInfo - { - public DepthStencilState DepthStencilState; - public GraphicsShaderInfo VertexShaderInfo; - public GraphicsShaderInfo FragmentShaderInfo; - public MultisampleState MultisampleState; - public RasterizerState RasterizerState; - public PrimitiveType PrimitiveType; - public VertexInputState VertexInputState; - public GraphicsPipelineAttachmentInfo AttachmentInfo; - public BlendConstants BlendConstants; - } -} diff --git a/src/Graphics/State/GraphicsShaderInfo.cs b/src/Graphics/State/GraphicsShaderInfo.cs deleted file mode 100644 index a0cee03..0000000 --- a/src/Graphics/State/GraphicsShaderInfo.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Runtime.InteropServices; - -namespace MoonWorks.Graphics -{ - /// - /// Information that the pipeline needs about a graphics shader. - /// - public struct GraphicsShaderInfo - { - public ShaderModule ShaderModule; - public string EntryPointName; - public uint UniformBufferSize; - public uint SamplerBindingCount; - - public unsafe static GraphicsShaderInfo Create( - ShaderModule shaderModule, - string entryPointName, - uint samplerBindingCount - ) where T : unmanaged - { - return new GraphicsShaderInfo - { - ShaderModule = shaderModule, - EntryPointName = entryPointName, - UniformBufferSize = (uint) Marshal.SizeOf(), - SamplerBindingCount = samplerBindingCount - }; - } - - public static GraphicsShaderInfo Create( - ShaderModule shaderModule, - string entryPointName, - uint samplerBindingCount - ) { - return new GraphicsShaderInfo - { - ShaderModule = shaderModule, - EntryPointName = entryPointName, - UniformBufferSize = 0, - SamplerBindingCount = samplerBindingCount - }; - } - } -} diff --git a/src/Graphics/State/MultisampleState.cs b/src/Graphics/State/MultisampleState.cs index acbcec0..925daf8 100644 --- a/src/Graphics/State/MultisampleState.cs +++ b/src/Graphics/State/MultisampleState.cs @@ -1,4 +1,6 @@ -namespace MoonWorks.Graphics +using SDL2_gpuCS; + +namespace MoonWorks.Graphics { /// /// Specifies how many samples should be used in rasterization. @@ -21,5 +23,14 @@ MultisampleCount = sampleCount; SampleMask = sampleMask; } + + public SDL_Gpu.MultisampleState ToSDL() + { + return new SDL_Gpu.MultisampleState + { + MultisampleCount = (SDL_Gpu.SampleCount) MultisampleCount, + SampleMask = SampleMask + }; + } } } diff --git a/src/Graphics/State/RasterizerState.cs b/src/Graphics/State/RasterizerState.cs index f14316f..ec44cad 100644 --- a/src/Graphics/State/RasterizerState.cs +++ b/src/Graphics/State/RasterizerState.cs @@ -1,107 +1,122 @@ -namespace MoonWorks.Graphics +using SDL2_gpuCS; + +namespace MoonWorks.Graphics; + +/// +/// Specifies how the rasterizer should be configured for a graphics pipeline. +/// +public struct RasterizerState { /// - /// Specifies how the rasterizer should be configured for a graphics pipeline. + /// Specifies whether front faces, back faces, none, or both should be culled. /// - public struct RasterizerState + public CullMode CullMode; + + /// + /// Specifies maximum depth bias of a fragment. Only applies if depth biasing is enabled. + /// + public float DepthBiasClamp; + + /// + /// The constant depth value added to each fragment. Only applies if depth biasing is enabled. + /// + public float DepthBiasConstantFactor; + + /// + /// Specifies whether depth biasing is enabled. Only applies if depth biasing is enabled. + /// + public bool DepthBiasEnable; + + /// + /// Factor applied to a fragment's slope in depth bias calculations. Only applies if depth biasing is enabled. + /// + public float DepthBiasSlopeFactor; + + /// + /// Specifies how triangles should be drawn. + /// + public FillMode FillMode; + + /// + /// Specifies which triangle winding order is designated as front-facing. + /// + public FrontFace FrontFace; + + public static readonly RasterizerState CW_CullFront = new RasterizerState { - /// - /// Specifies whether front faces, back faces, none, or both should be culled. - /// - public CullMode CullMode; + CullMode = CullMode.Front, + FrontFace = FrontFace.Clockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - /// - /// Specifies maximum depth bias of a fragment. Only applies if depth biasing is enabled. - /// - public float DepthBiasClamp; + public static readonly RasterizerState CW_CullBack = new RasterizerState + { + CullMode = CullMode.Back, + FrontFace = FrontFace.Clockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - /// - /// The constant depth value added to each fragment. Only applies if depth biasing is enabled. - /// - public float DepthBiasConstantFactor; + public static readonly RasterizerState CW_CullNone = new RasterizerState + { + CullMode = CullMode.None, + FrontFace = FrontFace.Clockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - /// - /// Specifies whether depth biasing is enabled. Only applies if depth biasing is enabled. - /// - public bool DepthBiasEnable; + public static readonly RasterizerState CW_Wireframe = new RasterizerState + { + CullMode = CullMode.None, + FrontFace = FrontFace.Clockwise, + FillMode = FillMode.Line, + DepthBiasEnable = false + }; - /// - /// Factor applied to a fragment's slope in depth bias calculations. Only applies if depth biasing is enabled. - /// - public float DepthBiasSlopeFactor; + public static readonly RasterizerState CCW_CullFront = new RasterizerState + { + CullMode = CullMode.Front, + FrontFace = FrontFace.CounterClockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - /// - /// Specifies how triangles should be drawn. - /// - public FillMode FillMode; + public static readonly RasterizerState CCW_CullBack = new RasterizerState + { + CullMode = CullMode.Back, + FrontFace = FrontFace.CounterClockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - /// - /// Specifies which triangle winding order is designated as front-facing. - /// - public FrontFace FrontFace; + public static readonly RasterizerState CCW_CullNone = new RasterizerState + { + CullMode = CullMode.None, + FrontFace = FrontFace.CounterClockwise, + FillMode = FillMode.Fill, + DepthBiasEnable = false + }; - public static readonly RasterizerState CW_CullFront = new RasterizerState + public static readonly RasterizerState CCW_Wireframe = new RasterizerState + { + CullMode = CullMode.None, + FrontFace = FrontFace.CounterClockwise, + FillMode = FillMode.Line, + DepthBiasEnable = false + }; + + public SDL_Gpu.RasterizerState ToSDL() + { + return new SDL_Gpu.RasterizerState { - CullMode = CullMode.Front, - FrontFace = FrontFace.Clockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CW_CullBack = new RasterizerState - { - CullMode = CullMode.Back, - FrontFace = FrontFace.Clockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CW_CullNone = new RasterizerState - { - CullMode = CullMode.None, - FrontFace = FrontFace.Clockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CW_Wireframe = new RasterizerState - { - CullMode = CullMode.None, - FrontFace = FrontFace.Clockwise, - FillMode = FillMode.Line, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CCW_CullFront = new RasterizerState - { - CullMode = CullMode.Front, - FrontFace = FrontFace.CounterClockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CCW_CullBack = new RasterizerState - { - CullMode = CullMode.Back, - FrontFace = FrontFace.CounterClockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CCW_CullNone = new RasterizerState - { - CullMode = CullMode.None, - FrontFace = FrontFace.CounterClockwise, - FillMode = FillMode.Fill, - DepthBiasEnable = false - }; - - public static readonly RasterizerState CCW_Wireframe = new RasterizerState - { - CullMode = CullMode.None, - FrontFace = FrontFace.CounterClockwise, - FillMode = FillMode.Line, - DepthBiasEnable = false + CullMode = (SDL_Gpu.CullMode) CullMode, + DepthBiasClamp = DepthBiasClamp, + DepthBiasConstantFactor = DepthBiasConstantFactor, + DepthBiasEnable = Conversions.BoolToInt(DepthBiasEnable), + DepthBiasSlopeFactor = DepthBiasSlopeFactor, + FillMode = (SDL_Gpu.FillMode) FillMode, + FrontFace = (SDL_Gpu.FrontFace) FrontFace }; } } diff --git a/src/Graphics/State/TextureCreateInfo.cs b/src/Graphics/State/TextureCreateInfo.cs index cddb2c1..1350fb8 100644 --- a/src/Graphics/State/TextureCreateInfo.cs +++ b/src/Graphics/State/TextureCreateInfo.cs @@ -1,4 +1,4 @@ -using RefreshCS; +using SDL2_gpuCS; namespace MoonWorks.Graphics { @@ -17,19 +17,19 @@ namespace MoonWorks.Graphics public TextureFormat Format; public TextureUsageFlags UsageFlags; - public Refresh.TextureCreateInfo ToRefreshTextureCreateInfo() + public SDL_Gpu.TextureCreateInfo ToSDL() { - return new Refresh.TextureCreateInfo + return new SDL_Gpu.TextureCreateInfo { - width = Width, - height = Height, - depth = Depth, - isCube = Conversions.BoolToByte(IsCube), - layerCount = LayerCount, - levelCount = LevelCount, - sampleCount = (Refresh.SampleCount) SampleCount, - format = (Refresh.TextureFormat) Format, - usageFlags = (Refresh.TextureUsageFlags) UsageFlags + Width = Width, + Height = Height, + Depth = Depth, + IsCube = Conversions.BoolToInt(IsCube), + LayerCount = LayerCount, + LevelCount = LevelCount, + SampleCount = (SDL_Gpu.SampleCount) SampleCount, + Format = (SDL_Gpu.TextureFormat) Format, + UsageFlags = (SDL_Gpu.TextureUsageFlags) UsageFlags }; } } diff --git a/src/Graphics/TextureRegion.cs b/src/Graphics/TextureRegion.cs index d1d853b..840ebe1 100644 --- a/src/Graphics/TextureRegion.cs +++ b/src/Graphics/TextureRegion.cs @@ -1,4 +1,4 @@ -using RefreshCS; +using SDL2_gpuCS; namespace MoonWorks.Graphics { @@ -29,17 +29,17 @@ namespace MoonWorks.Graphics Depth = texture.Depth; } - public Refresh.TextureRegion ToRefreshTextureRegion() + public SDL_Gpu.TextureRegion ToSDL() { - return new Refresh.TextureRegion + return new SDL_Gpu.TextureRegion { - textureSlice = TextureSlice.ToRefreshTextureSlice(), - x = X, - y = Y, - z = Z, - w = Width, - h = Height, - d = Depth + TextureSlice = TextureSlice.ToSDL(), + X = X, + Y = Y, + Z = Z, + W = Width, + H = Height, + D = Depth }; } }