Added new compute uniforms test, reworked existing compute test

pull/1/head
Caleb Cornett 2022-12-28 15:31:08 -05:00
parent c0213bafc8
commit 5ccfa7da7e
22 changed files with 195 additions and 16 deletions

View File

@ -64,8 +64,8 @@ namespace MoonWorks.Test
);
// Create buffers and textures
float[] squares = new float[64];
Buffer squaresBuffer = Buffer.Create<float>(
uint[] squares = new uint[64];
Buffer squaresBuffer = Buffer.Create<uint>(
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));
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\MoonWorks\MoonWorks.csproj" />
<ProjectReference Include="..\MoonWorks.Test.Common\MoonWorks.Test.Common.csproj" />
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<Platforms>x64</Platforms>
</PropertyGroup>
</Project>

View File

@ -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<GradientTextureComputeUniforms>(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<PositionTextureVertex>(),
VertexAttribute.Create<PositionTextureVertex>("Position", 0),
VertexAttribute.Create<PositionTextureVertex>("TexCoord", 1)
);
drawPipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1;
drawPipeline = new GraphicsPipeline(
GraphicsDevice,
drawPipelineCreateInfo
);
// Create buffers and textures
vertexBuffer = Buffer.Create<PositionTextureVertex>(
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();
}
}
}

View File

@ -3,7 +3,7 @@
layout (local_size_x = 8) in;
layout (set = 0, binding = 0) buffer outBuffer
{
float squares[];
uint squares[];
};
void main()

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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

View File

@ -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.