From 5ccfa7da7e73854ebf0f1b933a1f785449c78894 Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Wed, 28 Dec 2022 15:31:08 -0500 Subject: [PATCH] Added new compute uniforms test, reworked existing compute test --- BasicCompute/BasicComputeGame.cs | 14 +- ComputeUniforms/ComputeUniforms.csproj | 15 ++ ComputeUniforms/ComputeUniformsGame.cs | 134 ++++++++++++++++++ .../Compiled/CalculateSquaresCompute.spv | Bin 944 -> 916 bytes .../Shaders/Compiled/FillTextureCompute.spv | Bin 1412 -> 888 bytes .../Compiled/GradientTextureCompute.spv | Bin 0 -> 1548 bytes .../Shaders/Compiled/PositionColorVert.spv | Bin 1052 -> 1052 bytes .../Compiled/PositionColorVertWithMatrix.spv | Bin 1348 -> 1348 bytes .../Shaders/Compiled/RawTriangleVertices.spv | Bin 1568 -> 1568 bytes .../Content/Shaders/Compiled/SkyboxFrag.spv | Bin 640 -> 640 bytes .../Content/Shaders/Compiled/SkyboxVert.spv | Bin 1276 -> 1276 bytes .../Content/Shaders/Compiled/SolidColor.spv | Bin 448 -> 448 bytes .../Compiled/TexturedDepthQuadFrag.spv | Bin 1648 -> 1648 bytes .../Shaders/Compiled/TexturedQuadFrag.spv | Bin 632 -> 632 bytes .../TexturedQuadFragWithMultiplyColor.spv | Bin 908 -> 908 bytes .../Shaders/Compiled/TexturedQuadVert.spv | Bin 1088 -> 1088 bytes .../Compiled/TexturedQuadVertWithMatrix.spv | Bin 1384 -> 1384 bytes .../Source/CalculateSquaresCompute.comp | 2 +- .../Shaders/Source/FillTextureCompute.comp | 9 +- .../Source/GradientTextureCompute.comp | 23 +++ MoonWorksGraphicsTests.sln | 8 +- README.md | 6 +- 22 files changed, 195 insertions(+), 16 deletions(-) create mode 100644 ComputeUniforms/ComputeUniforms.csproj create mode 100644 ComputeUniforms/ComputeUniformsGame.cs create mode 100644 MoonWorks.Test.Common/Content/Shaders/Compiled/GradientTextureCompute.spv create mode 100644 MoonWorks.Test.Common/Content/Shaders/Source/GradientTextureCompute.comp 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 85c5807043e07c672c0deafbd087e16f1098a9fd..5492e6f5409397175911cef00ac67a846c88c840 100644 GIT binary patch delta 391 zcmYk1%}&Bl5QV2L&=S)``B4yCfvyO!H!(5F2DUtc3t(vkyLRKAkhv?!7<$w;y_L;+r{kVWHh`!d>sm%-+(EQ97T`meeIHnmonoJ$+ryRydwj zv!TCRD|bewIS^=Cx?d2^g^kZv~8grOw)!NmJ}z;)m^ehZ0yh z8G6mT3)C#gfYph!4_7R4syjH;87q@}K(VAtynA3r?viiseaFg;XwL<+@WO+4P=Xy!oY+$()p+l_!w;bom4q!6ron-Gn xCX=9kKTX>ksOo;_Gc@iJ)PeM8JX+NR(&spIg%;4Yb+sCp@l0v*{jqxl{sCP%8`}T? diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/FillTextureCompute.spv index 07b7b820d2275bbc1aec73dadaeb34ad6f64b87f..3f90d1599c6f117939ac1c8283434414b283b594 100644 GIT binary patch delta 332 zcmYL_I|>3Z7=&kyyS~`Q_5E1UtwhB}K@hRDv9Yuiv9Qo9XyFAU$FLGSoQ>d2Kn%=I zzRl#%pWF)XAT+5Y19&JPMCTq(qX0gDGw)oJdM~sy@y{%4w3DfP2D!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 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 0000000000000000000000000000000000000000..43fe8c97025de8924f8586ed0c922fa2b95afb6f GIT binary patch literal 1548 zcmY+E+fNfw5XMhiN)hBH0^$W*zzb6A4G<-2Fq*YVlbR6X8~jLOU{IuHeSp3+HJ4(-VX)?|2+K~ z_53J|dww?@_JTCL=)s%H@xnNWM%_H2EJnUR{w4JYl4RJGE-Rls^&{VllG9Gqj4zU) zlZHv$e3!*5=8ANhq@CzfGW^^hCZoY|_)Wdb+V7HLCvV$2Q6;nGnlJy;GTyTA(P@&| zHQ7ND$u65`vXfETJnQsT(HKwrV?Q&Jo01RW(1W!(R^p8Na#!%Fy&=i_^k5OE2XXG$ z`TydjEWT!AFQw^?zod%PtYwoK*I$u6DXc14Rc$?x%!gN%&pg49W%<(?u76tasSU;} zfqz-LAOSzLKIaF6KPL^J`s?=GVB}u4IQK&?K6e3^-Ye2o3AJ{tzbczW{xxa1)FaNh zxO1(ey6&Ab+>(GH?B}*LJl+&Fs?zYlsli@1BrM|0j5s+izAd|8eeg#TW4^yx)60A! z3ygSvu}|0YsSUv8-1y9x#UA&iIXgM7=L^})rmpJTHFE|-*w4Ps>w3t|=JQ(!-!DDL z<-6f5&gZ*uepPnO`me;N$Gn7Dw#DL(7c2(O;*0}vsljgn@z?51AN(VAXGXk5=F04- zO|9z^aF>6>Vn6KM*5!jSKWeg9FlsWBEeU;?6*al@I}&imxhtEzJm;Q#@Smzf&V31a z;4bfhY-(>yTRKnU|?k6-pERKnU|?k6+Q?bX1OOO50)YSk diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/SkyboxVert.spv index 4c4a358b7a33fc63e0daafba00c763b8a2fc633b..d7d0ddacabb7327c943727d94396ca1cb406f897 100644 GIT binary patch delta 18 Zcmeyv`G=E}nMs+Qfq{{Mdn4y(762+W1ONa4 delta 18 Zcmeyv`G=E}nMs+Qfq{{MYa{1p762+R1OEU3 diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/SolidColor.spv index 211b356b7e8573cadd3314880f66592e39a65879..2c37cf617945af0dafe17fd4f8c2b2be4d22f5d4 100644 GIT binary patch delta 18 ZcmX@We1MsgnMs+Qfq{{Mdn4y|MgSoK13dr$ delta 18 ZcmX@We1MsgnMs+Qfq{{MYa{1&MgSoF13Ul# diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedDepthQuadFrag.spv index 882034baf2943aaf82ae57e939ccfaaa12c032ed..e64dcd45a973ea7d6d56ed2bd7b3baa6015230a8 100644 GIT binary patch delta 18 Zcmeys^MQwxnMs+Qfq{{Mdn0E$8vrNg17rXI delta 18 Zcmeys^MQwxnMs+Qfq{{MYa?em8vrNb17iRH diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFrag.spv index d19ad274fe08559641dc054e2d20e92734ced432..f3a7af5975660ddea401613500997901f0e87955 100644 GIT binary patch delta 18 Zcmeyt@`HtwnMs+Qfq{{Mdn0E)696a!184vM delta 18 Zcmeyt@`HtwnMs+Qfq{{MYa?eq696av17`pL diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadFragWithMultiplyColor.spv index fa849a9e7064c46059d299fa2940847f3c66f587..0c4dc460c7df1ecf2a554f60d72a50c3174c0f4c 100644 GIT binary patch delta 18 ZcmeBS?_uX;W>RKnU|?k6-pJX^3;-H50;>Q3 delta 18 ZcmeBS?_uX;W>RKnU|?k6+Q`|=3;-H00;&K2 diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVert.spv index c565481e90e65095ffbfe2b7e29e697dd39b27f6..1b444a6397f46f5565fd624113c20a9fbc61d419 100644 GIT binary patch delta 18 ZcmX@Wae#x9nMs+Qfq{{Mdn2bg3jiRc0?GgY delta 18 ZcmX@Wae#x9nMs+Qfq{{MYa^#Q3jiRX0?7aX diff --git a/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv b/MoonWorks.Test.Common/Content/Shaders/Compiled/TexturedQuadVertWithMatrix.spv index e43dee242fb9dd64b943cf2263d6a42e298ee9de..95270cd02d3469289b05719cc86331a564e150bd 100644 GIT binary patch delta 18 ZcmaFC^@59&nMs+Qfq{{Mdn0E&D*z^j14jS= delta 18 ZcmaFC^@59&nMs+Qfq{{MYa?eoD*z^e14aM< 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.