From 31c79d31798f42e0f922b3673330650f75956cd1 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 23 Feb 2024 12:39:59 -0800 Subject: [PATCH] built-in Blit operation --- MoonWorks.csproj | 7 +- src/Graphics/CommandBuffer.cs | 21 +++++ src/Graphics/GraphicsDevice.cs | 77 +++++++++++++++--- src/Graphics/Resources/TransferBuffer.cs | 2 +- .../StockShaders/Binary/blit.frag.refresh | Bin 0 -> 645 bytes ...n.vert.refresh => fullscreen.vert.refresh} | Bin src/Graphics/StockShaders/Source/blit.frag | 12 +++ ...{video_fullscreen.vert => fullscreen.vert} | 0 8 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 src/Graphics/StockShaders/Binary/blit.frag.refresh rename src/Graphics/StockShaders/Binary/{video_fullscreen.vert.refresh => fullscreen.vert.refresh} (100%) create mode 100644 src/Graphics/StockShaders/Source/blit.frag rename src/Graphics/StockShaders/Source/{video_fullscreen.vert => fullscreen.vert} (100%) diff --git a/MoonWorks.csproj b/MoonWorks.csproj index 2e0eb18..a1e1f4e 100644 --- a/MoonWorks.csproj +++ b/MoonWorks.csproj @@ -26,8 +26,8 @@ - - MoonWorks.Graphics.StockShaders.VideoFullscreen.vert.refresh + + MoonWorks.Graphics.StockShaders.Fullscreen.vert.refresh MoonWorks.Graphics.StockShaders.VideoYUV2RGBA.frag.refresh @@ -38,5 +38,8 @@ MoonWorks.Graphics.StockShaders.TextMSDF.frag.refresh + + MoonWorks.Graphics.StockShaders.Blit.frag.refresh + diff --git a/src/Graphics/CommandBuffer.cs b/src/Graphics/CommandBuffer.cs index c53d5d0..e44d53b 100644 --- a/src/Graphics/CommandBuffer.cs +++ b/src/Graphics/CommandBuffer.cs @@ -87,6 +87,7 @@ namespace MoonWorks.Graphics ) { #if DEBUG AssertNotSubmitted(); + AssertNotInPass("Cannot begin a render pass inside another pass!"); AssertTextureNotNull(colorAttachmentInfo); AssertColorTarget(colorAttachmentInfo); #endif @@ -528,6 +529,7 @@ namespace MoonWorks.Graphics public void BeginComputePass() { #if DEBUG + AssertNotSubmitted(); AssertNotInPass("Cannot begin compute pass while in another pass!"); computePassActive = true; #endif @@ -1844,6 +1846,25 @@ namespace MoonWorks.Graphics #endif } + /// + /// Blits a texture to another texture with the specified filter. + /// + /// This operation cannot be performed inside any pass. + /// + public void Blit( + Texture source, + Texture destination, + Filter filter + ) { + var sampler = filter == Filter.Linear ? Device.LinearSampler : Device.PointSampler; + + BeginRenderPass(new ColorAttachmentInfo(destination)); + BindGraphicsPipeline(Device.BlitPipeline); + BindFragmentSamplers(new TextureSamplerBinding(source, sampler)); + DrawPrimitives(0, 2); + EndRenderPass(); + } + /// /// Acquires a swapchain texture. /// This texture will be presented to the given window when the command buffer is submitted. diff --git a/src/Graphics/GraphicsDevice.cs b/src/Graphics/GraphicsDevice.cs index 7293f02..ce7c865 100644 --- a/src/Graphics/GraphicsDevice.cs +++ b/src/Graphics/GraphicsDevice.cs @@ -22,6 +22,9 @@ namespace MoonWorks.Graphics // Built-in video pipeline internal GraphicsPipeline VideoPipeline { get; } + // Built-in blit pipeline + internal GraphicsPipeline BlitPipeline { get; } + // Built-in text shader info public GraphicsShaderInfo TextVertexShaderInfo { get; } public GraphicsShaderInfo TextFragmentShaderInfo { get; } @@ -57,32 +60,43 @@ namespace MoonWorks.Graphics // Check for replacement stock shaders string basePath = System.AppContext.BaseDirectory; - string videoVertPath = Path.Combine(basePath, "video_fullscreen.vert.refresh"); - string videoFragPath = Path.Combine(basePath, "video_yuv2rgba.frag.refresh"); + string fullscreenVertPath = Path.Combine(basePath, "fullscreen.vert.refresh"); string textVertPath = Path.Combine(basePath, "text_transform.vert.refresh"); string textFragPath = Path.Combine(basePath, "text_msdf.frag.refresh"); - ShaderModule videoVertShader; - ShaderModule videoFragShader; + string videoFragPath = Path.Combine(basePath, "video_yuv2rgba.frag.refresh"); + string blitFragPath = Path.Combine(basePath, "blit.frag.refresh"); + + ShaderModule fullscreenVertShader; ShaderModule textVertShader; ShaderModule textFragShader; - if (File.Exists(videoVertPath) && File.Exists(videoFragPath)) + ShaderModule videoFragShader; + ShaderModule blitFragShader; + + if (File.Exists(fullscreenVertPath)) + { + fullscreenVertShader = new ShaderModule(this, fullscreenVertPath); + } + else + { + // use defaults + var assembly = typeof(GraphicsDevice).Assembly; + using var vertStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.Fullscreen.vert.refresh"); + fullscreenVertShader = new ShaderModule(this, vertStream); + } + + if (File.Exists(videoFragPath)) { - videoVertShader = new ShaderModule(this, videoVertPath); videoFragShader = new ShaderModule(this, videoFragPath); } else { // use defaults var assembly = typeof(GraphicsDevice).Assembly; - - using var vertStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.VideoFullscreen.vert.refresh"); using var fragStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.VideoYUV2RGBA.frag.refresh"); - - videoVertShader = new ShaderModule(this, vertStream); videoFragShader = new ShaderModule(this, fragStream); } @@ -103,6 +117,19 @@ namespace MoonWorks.Graphics textFragShader = new ShaderModule(this, fragStream); } + if (File.Exists(blitFragPath)) + { + blitFragShader = new ShaderModule(this, blitFragPath); + } + else + { + // use defaults + var assembly = typeof(GraphicsDevice).Assembly; + + using var fragStream = assembly.GetManifestResourceStream("MoonWorks.Graphics.StockShaders.Blit.frag.refresh"); + blitFragShader = new ShaderModule(this, fragStream); + } + VideoPipeline = new GraphicsPipeline( this, new GraphicsPipelineCreateInfo @@ -115,7 +142,7 @@ namespace MoonWorks.Graphics ), DepthStencilState = DepthStencilState.Disable, VertexShaderInfo = GraphicsShaderInfo.Create( - videoVertShader, + fullscreenVertShader, "main", 0 ), @@ -131,6 +158,34 @@ namespace MoonWorks.Graphics } ); + BlitPipeline = new GraphicsPipeline( + this, + new GraphicsPipelineCreateInfo + { + AttachmentInfo = new GraphicsPipelineAttachmentInfo( + new ColorAttachmentDescription( + TextureFormat.R8G8B8A8, + ColorAttachmentBlendState.None + ) + ), + DepthStencilState = DepthStencilState.Disable, + VertexShaderInfo = GraphicsShaderInfo.Create( + fullscreenVertShader, + "main", + 0 + ), + FragmentShaderInfo = GraphicsShaderInfo.Create( + blitFragShader, + "main", + 1 + ), + VertexInputState = VertexInputState.Empty, + RasterizerState = RasterizerState.CCW_CullNone, + PrimitiveType = PrimitiveType.TriangleList, + MultisampleState = MultisampleState.None + } + ); + TextVertexShaderInfo = GraphicsShaderInfo.Create(textVertShader, "main", 0); TextFragmentShaderInfo = GraphicsShaderInfo.Create(textFragShader, "main", 1); TextVertexInputState = VertexInputState.CreateSingleBinding(); diff --git a/src/Graphics/Resources/TransferBuffer.cs b/src/Graphics/Resources/TransferBuffer.cs index b93200d..bb94aa2 100644 --- a/src/Graphics/Resources/TransferBuffer.cs +++ b/src/Graphics/Resources/TransferBuffer.cs @@ -113,7 +113,7 @@ namespace MoonWorks.Graphics /// public unsafe void GetData( Span data, - uint bufferOffsetInBytes + uint bufferOffsetInBytes = 0 ) where T : unmanaged { var elementSize = Marshal.SizeOf(); diff --git a/src/Graphics/StockShaders/Binary/blit.frag.refresh b/src/Graphics/StockShaders/Binary/blit.frag.refresh new file mode 100644 index 0000000000000000000000000000000000000000..ac3850ae3ef5304990776ec6f1f7587bd7c0e3fb GIT binary patch literal 645 zcmYk2OH0F05QV3Y*xK5c6-5MTbzfYl2%?)}<04S7g3C~vAc3?gX%z*3oxjSB;Q3+; z8JNsHC+D7-xlg0XW8tf4Rw|xX%nDYwh8@^{bgU@G#O-9&^(Nk6wGIZCR~IOnR?38E zT2`^LDmkA<3x4b>JIc0n@M@q_Nv>w!x>UBBxt{Ni$FBF_&z4Jnwf>AlKaLimA4F+5 zTSxC9x@t}rEoSjskQX>o