From 4f0a053e0042122f114d5bdfc9ded33cca64cc51 Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Sat, 12 Nov 2022 18:20:02 -0500 Subject: [PATCH] add BasicCompute test --- BasicCompute/BasicCompute.csproj | 15 +++ BasicCompute/BasicComputeGame.cs | 108 ++++++++++++++++++ .../Shaders/Compiled/FillTextureCompute.spv | Bin 0 -> 1412 bytes .../Shaders/Source/FillTextureCompute.comp | 17 +++ MoonWorksGraphicsTests.sln | 6 + README.md | 4 + 6 files changed, 150 insertions(+) create mode 100644 BasicCompute/BasicCompute.csproj create mode 100644 BasicCompute/BasicComputeGame.cs create mode 100644 MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv create mode 100644 MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp diff --git a/BasicCompute/BasicCompute.csproj b/BasicCompute/BasicCompute.csproj new file mode 100644 index 0000000..a8d5981 --- /dev/null +++ b/BasicCompute/BasicCompute.csproj @@ -0,0 +1,15 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + diff --git a/BasicCompute/BasicComputeGame.cs b/BasicCompute/BasicComputeGame.cs new file mode 100644 index 0000000..77874cd --- /dev/null +++ b/BasicCompute/BasicComputeGame.cs @@ -0,0 +1,108 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class BasicComputeGame : Game + { + private GraphicsPipeline drawPipeline; + private Texture texture; + private Sampler sampler; + private Buffer vertexBuffer; + + public BasicComputeGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + ShaderModule computeShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("FillTextureCompute.spv") + ); + + ComputePipeline computePipeline = new ComputePipeline( + GraphicsDevice, + ComputeShaderInfo.Create(computeShaderModule, "main", 0, 1) + ); + + ShaderModule vertShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuadVert.spv") + ); + + ShaderModule fragShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuadFrag.spv") + ); + + GraphicsPipelineCreateInfo drawPipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + vertShaderModule, + fragShaderModule + ); + drawPipelineCreateInfo.VertexInputState = new VertexInputState( + VertexBinding.Create(), + VertexAttribute.Create("Position", 0), + VertexAttribute.Create("TexCoord", 1) + ); + drawPipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; + + drawPipeline = new GraphicsPipeline( + GraphicsDevice, + drawPipelineCreateInfo + ); + + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 6); + + // Create the texture that will be filled in by the compute pipeline + texture = Texture.CreateTexture2D( + GraphicsDevice, + MainWindow.Width, + MainWindow.Height, + TextureFormat.R8G8B8A8, + TextureUsageFlags.Compute | TextureUsageFlags.Sampler + ); + sampler = new Sampler(GraphicsDevice, new SamplerCreateInfo()); + + // Populate the vertex buffer and run the compute shader to generate the texture data + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + + cmdbuf.SetBufferData(vertexBuffer, new PositionTextureVertex[] + { + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, -1, 0), new Vector2(1, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(1, 1)), + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(1, 1)), + new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 1)), + }); + + cmdbuf.BindComputePipeline(computePipeline); + cmdbuf.BindComputeTextures(texture); + cmdbuf.DispatchCompute(MainWindow.Width / 8, MainWindow.Height / 8, 1, 0); + + GraphicsDevice.Submit(cmdbuf); + } + + protected override void Update(System.TimeSpan delta) { } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.CornflowerBlue)); + cmdbuf.BindGraphicsPipeline(drawPipeline); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(texture, sampler)); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.DrawPrimitives(0, 2, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + BasicComputeGame game = new BasicComputeGame(); + game.Run(); + } + } +} diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv new file mode 100644 index 0000000000000000000000000000000000000000..07b7b820d2275bbc1aec73dadaeb34ad6f64b87f GIT binary patch literal 1412 zcmYk6+fNfw5XQ&0OA+KI0^)TG-obhUG%;#SB%3CUHQ~X>P2D!l#-*oewwXM}SiO1`SymP}kGJ+K$j z-865Vb_dEdi*ye9E($kFn_AdcOPib>f!Pp`-4OU9)yLj0^qO6hBo}*KQ)G^fVxm^) z8_J&(7YfwdlC1?79I>Hnb^!;7UnqF}(nmb?;n*_qmn5kL|GKofldr!lop|bRD(kXj zC{Sx%65H3hBAveQz83SK)}G?2!(2F{x4A3+ecggHFau%$KKk60qz`X^GvAV=54^7v zO6SAhki>sJtD4;{ZE6sYd?J|re7CKa^h_EY=a~Jtv+w!5bP&tku-P5ok=}-n#bzFV z#RQVXa$nvnXToMqyhm?yAKn@E8~K^TiohN^V%foJ$-(n+)*p%`hrdDmZ`GMT*uKt| zbawDdr=jk30ggG3l+UhsyYS?5F6{S;XO24pHA8`#%yd_Pce0t=osuJmS>F?=6AI)I zb6-VOik rI0HW30^t7a0U!O@^?|^iv6=Ouz!|Zrb0if1BV-ecAMT$v^h)>-rN&^r literal 0 HcmV?d00001 diff --git a/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp b/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp new file mode 100644 index 0000000..8828003 --- /dev/null +++ b/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp @@ -0,0 +1,17 @@ +#version 450 + +layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout (set = 1, binding = 0, rgba8) uniform writeonly image2D outImage; + +void main() +{ + ivec2 coord = ivec2(gl_GlobalInvocationID.xy); + vec3 totalWorkgroupSize = gl_NumWorkGroups * gl_WorkGroupSize; + vec4 col = vec4( + float(coord.x) / totalWorkgroupSize.x, + float(coord.y) / totalWorkgroupSize.y, + 1.0, + 1.0 + ); + imageStore(outImage, coord, col); +} diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index 32fcc2a..eb87a27 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -27,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MoonWorks", "..\MoonWorks\M EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cube", "Cube\Cube.csproj", "{C3808AFD-23DD-4622-BFA7-981A344D0C19}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicCompute", "BasicCompute\BasicCompute.csproj", "{68D47057-BBCB-4F86-9C0A-D6D730B18D9E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -81,6 +83,10 @@ Global {C3808AFD-23DD-4622-BFA7-981A344D0C19}.Debug|x64.Build.0 = Debug|x64 {C3808AFD-23DD-4622-BFA7-981A344D0C19}.Release|x64.ActiveCfg = Release|Any CPU {C3808AFD-23DD-4622-BFA7-981A344D0C19}.Release|x64.Build.0 = Release|Any CPU + {68D47057-BBCB-4F86-9C0A-D6D730B18D9E}.Debug|x64.ActiveCfg = Debug|x64 + {68D47057-BBCB-4F86-9C0A-D6D730B18D9E}.Debug|x64.Build.0 = Debug|x64 + {68D47057-BBCB-4F86-9C0A-D6D730B18D9E}.Release|x64.ActiveCfg = Release|Any CPU + {68D47057-BBCB-4F86-9C0A-D6D730B18D9E}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 3f0706b..199bfbc 100644 --- a/README.md +++ b/README.md @@ -39,3 +39,7 @@ Sets buffer data, gets the data back from the GPU, and prints the results to the **Cube** Renders a cubemap skybox and a spinning cube. Tests depth textures, sampling from depth textures, depth-only render passes, cube textures, and 32-bit index buffers. + +**BasicCompute** + +Uses a compute pipeline to fill a texture with data, then displays it to the screen. Tests compute pipeline creation and compute dispatching.