diff --git a/BasicCompute/BasicComputeGame.cs b/BasicCompute/BasicComputeGame.cs index def3193..7d4d3c5 100644 --- a/BasicCompute/BasicComputeGame.cs +++ b/BasicCompute/BasicComputeGame.cs @@ -64,8 +64,8 @@ namespace MoonWorks.Test ); // Create buffers and textures - float[] squares = new float[64]; - Buffer squaresBuffer = Buffer.Create( + uint[] squares = new uint[64]; + Buffer squaresBuffer = Buffer.Create( GraphicsDevice, BufferUsageFlags.Compute, (uint) squares.Length @@ -89,6 +89,7 @@ namespace MoonWorks.Test // Upload GPU resources and dispatch compute work CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData(vertexBuffer, new PositionTextureVertex[] { new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), @@ -99,18 +100,21 @@ namespace MoonWorks.Test new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 1)), }); + // This should result in a bright yellow texture! cmdbuf.BindComputePipeline(fillTextureComputePipeline); cmdbuf.BindComputeTextures(texture); - cmdbuf.DispatchCompute(MainWindow.Width / 8, MainWindow.Height / 8, 1, 0); + cmdbuf.DispatchCompute(texture.Width / 8, texture.Height / 8, 1, 0); + // This calculates the squares of the first N integers! cmdbuf.BindComputePipeline(calculateSquaresComputePipeline); cmdbuf.BindComputeBuffers(squaresBuffer); - cmdbuf.DispatchCompute(64, 1, 1, 0); + cmdbuf.DispatchCompute((uint) squares.Length / 8, 1, 1, 0); GraphicsDevice.Submit(cmdbuf); GraphicsDevice.Wait(); - squaresBuffer.GetData(squares, (uint) (sizeof(float) * squares.Length)); + // Print the squares! + squaresBuffer.GetData(squares, (uint) (sizeof(uint) * squares.Length)); Logger.LogInfo("Squares of the first " + squares.Length + " integers: " + string.Join(", ", squares)); } diff --git a/ComputeUniforms/ComputeUniforms.csproj b/ComputeUniforms/ComputeUniforms.csproj new file mode 100644 index 0000000..3d96325 --- /dev/null +++ b/ComputeUniforms/ComputeUniforms.csproj @@ -0,0 +1,15 @@ + + + + + + + + + Exe + net6.0 + enable + x64 + + + diff --git a/ComputeUniforms/ComputeUniformsGame.cs b/ComputeUniforms/ComputeUniformsGame.cs new file mode 100644 index 0000000..c54f2cf --- /dev/null +++ b/ComputeUniforms/ComputeUniformsGame.cs @@ -0,0 +1,134 @@ +using MoonWorks; +using MoonWorks.Graphics; +using MoonWorks.Math.Float; + +namespace MoonWorks.Test +{ + class ComputeUniformsGame : Game + { + private GraphicsPipeline drawPipeline; + private Texture texture; + private Sampler sampler; + private Buffer vertexBuffer; + + struct GradientTextureComputeUniforms + { + public uint groupCountX; + public uint groupCountY; + + public GradientTextureComputeUniforms(uint w, uint h) + { + groupCountX = w; + groupCountY = h; + } + } + + public ComputeUniformsGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + // Create the compute pipeline that writes texture data + ShaderModule gradientTextureComputeShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("GradientTextureCompute.spv") + ); + + ComputePipeline gradientTextureComputePipeline = new ComputePipeline( + GraphicsDevice, + ComputeShaderInfo.Create(gradientTextureComputeShaderModule, "main", 0, 1) + ); + + // Create the graphics pipeline + ShaderModule vertShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuadVert.spv") + ); + + ShaderModule fragShaderModule = new ShaderModule( + GraphicsDevice, + TestUtils.GetShaderPath("TexturedQuadFrag.spv") + ); + + GraphicsPipelineCreateInfo drawPipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + MainWindow.SwapchainFormat, + 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 + ); + + // Create buffers and textures + vertexBuffer = Buffer.Create( + GraphicsDevice, + BufferUsageFlags.Vertex, + 6 + ); + + texture = Texture.CreateTexture2D( + GraphicsDevice, + MainWindow.Width, + MainWindow.Height, + TextureFormat.R8G8B8A8, + TextureUsageFlags.Compute | TextureUsageFlags.Sampler + ); + + sampler = new Sampler(GraphicsDevice, new SamplerCreateInfo()); + + // Upload GPU resources and dispatch compute work + 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)), + }); + + GradientTextureComputeUniforms gradientUniforms = new GradientTextureComputeUniforms( + texture.Width / 8, + texture.Height / 8 + ); + + cmdbuf.BindComputePipeline(gradientTextureComputePipeline); + cmdbuf.BindComputeTextures(texture); + cmdbuf.PushComputeShaderUniforms(gradientUniforms); + cmdbuf.DispatchCompute(gradientUniforms.groupCountX, gradientUniforms.groupCountY, 1, 0); + + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + } + + 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) + { + ComputeUniformsGame game = new ComputeUniformsGame(); + game.Run(); + } + } +} diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/CalculateSquaresCompute.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/CalculateSquaresCompute.spv index 85c5807..5492e6f 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/CalculateSquaresCompute.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/CalculateSquaresCompute.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv index 07b7b82..3f90d15 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/GradientTextureCompute.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/GradientTextureCompute.spv new file mode 100644 index 0000000..43fe8c9 Binary files /dev/null and b/MoonWorks.Test.Common/Content/Shaders/Compiled/GradientTextureCompute.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv index 0852ff8..35c29f8 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVert.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVertWithMatrix.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVertWithMatrix.spv index 033f897..8676f66 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVertWithMatrix.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/PositionColorVertWithMatrix.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv index 917342f..68f5351 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/RawTriangleVertices.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxFrag.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxFrag.spv index b7b8249..1843fea 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxFrag.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxFrag.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv index 4c4a358..d7d0dda 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv index 211b356..2c37cf6 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv index 882034b..e64dcd4 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv index d19ad27..f3a7af5 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv index fa849a9..0c4dc46 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv index c565481..1b444a6 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv index e43dee2..95270cd 100644 Binary files a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv and b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv differ diff --git a/MoonWorks.Test.Common/Content/Shaders/Source/CalculateSquaresCompute.comp b/MoonWorks.Test.Common/Content/Shaders/Source/CalculateSquaresCompute.comp index ec3e8f2..888772a 100644 --- a/MoonWorks.Test.Common/Content/Shaders/Source/CalculateSquaresCompute.comp +++ b/MoonWorks.Test.Common/Content/Shaders/Source/CalculateSquaresCompute.comp @@ -3,7 +3,7 @@ layout (local_size_x = 8) in; layout (set = 0, binding = 0) buffer outBuffer { - float squares[]; + uint squares[]; }; void main() diff --git a/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp b/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp index 8828003..13111c3 100644 --- a/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp +++ b/MoonWorks.Test.Common/Content/Shaders/Source/FillTextureCompute.comp @@ -6,12 +6,5 @@ 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); + imageStore(outImage, coord, vec4(1.0, 1.0, 0.0, 1.0)); } diff --git a/MoonWorks.Test.Common/Content/Shaders/Source/GradientTextureCompute.comp b/MoonWorks.Test.Common/Content/Shaders/Source/GradientTextureCompute.comp new file mode 100644 index 0000000..5541446 --- /dev/null +++ b/MoonWorks.Test.Common/Content/Shaders/Source/GradientTextureCompute.comp @@ -0,0 +1,23 @@ +#version 450 + +#define LOCAL_SIZE 8 + +layout (local_size_x = LOCAL_SIZE, local_size_y = LOCAL_SIZE, local_size_z = 1) in; +layout (set = 1, binding = 0, rgba8) uniform writeonly image2D outImage; +layout(set = 2, binding = 0) uniform UBO +{ + uvec2 workgroupSize; +} ubo; + +void main() +{ + vec2 coord = gl_GlobalInvocationID.xy; + vec2 totalWorkgroupSize = vec2(ubo.workgroupSize) * vec2(LOCAL_SIZE); + vec4 col = vec4( + coord.x / totalWorkgroupSize.x, + coord.y / totalWorkgroupSize.y, + 1.0, + 1.0 + ); + imageStore(outImage, ivec2(coord), col); +} diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index eb87a27..53dd780 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -27,7 +27,9 @@ 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}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicCompute", "BasicCompute\BasicCompute.csproj", "{68D47057-BBCB-4F86-9C0A-D6D730B18D9E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComputeUniforms", "ComputeUniforms\ComputeUniforms.csproj", "{5F8BBD49-6C39-4186-A4A3-91D6662D3ABD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -87,6 +89,10 @@ Global {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 + {5F8BBD49-6C39-4186-A4A3-91D6662D3ABD}.Debug|x64.ActiveCfg = Debug|x64 + {5F8BBD49-6C39-4186-A4A3-91D6662D3ABD}.Debug|x64.Build.0 = Debug|x64 + {5F8BBD49-6C39-4186-A4A3-91D6662D3ABD}.Release|x64.ActiveCfg = Release|Any CPU + {5F8BBD49-6C39-4186-A4A3-91D6662D3ABD}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 17333b5..4611abd 100644 --- a/README.md +++ b/README.md @@ -42,4 +42,8 @@ Renders a cubemap skybox and a spinning cube. Tests depth textures, sampling fro **BasicCompute** -Uses compute pipelines to (1) fill a texture with data then display it to the screen and (2) calculate the squares of the first 64 integers. Tests compute pipeline creation, compute dispatching, compute textures, and compute buffers. +Uses compute pipelines to (1) fill a texture with yellow pixels then display it to the screen and (2) calculate the squares of the first 64 integers. Tests compute pipeline creation, compute dispatching, compute textures, and compute buffers. + +**ComputeUniforms** + +Uses a compute pipeline to fill a texture with a color gradient. Tests compute uniforms.