Skip to content

Commit

Permalink
Update lab WebGPU code
Browse files Browse the repository at this point in the history
  • Loading branch information
Beyley committed Sep 23, 2023
1 parent 06f3514 commit 630529f
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 84 deletions.
80 changes: 40 additions & 40 deletions src/Lab/Experiments/WebGPUTexturedQuad/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Silk.NET.Core.Native;
using Silk.NET.Maths;
using Silk.NET.WebGPU;
using Silk.NET.WebGPU.Extensions.Disposal;
using Silk.NET.WebGPU.Extensions.WGPU;
using Silk.NET.Windowing;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
Expand All @@ -31,16 +27,16 @@ public Vertex(Vector2 position, Vector2 texCoord)

// ReSharper disable once InconsistentNaming
private static WebGPU wgpu = null!;
private static IWindow? _Window;
private static IWindow _Window = null!;

private static Instance* _Instance;
private static Surface* _Surface;
private static SurfaceCapabilities _SurfaceCapabilities;
private static SurfaceConfiguration _SurfaceConfiguration;
private static Adapter* _Adapter;
private static Device* _Device;
private static ShaderModule* _Shader;
private static RenderPipeline* _Pipeline;
private static SwapChain* _SwapChain;
private static TextureFormat _SwapChainFormat;

private static Buffer* _VertexBuffer;
private static ulong _VertexBufferSize;
Expand Down Expand Up @@ -87,8 +83,7 @@ private static void WindowOnLoad()
{
wgpu = WebGPU.GetApi();

InstanceDescriptor instanceDescriptor = new InstanceDescriptor();
_Instance = wgpu.CreateInstance(instanceDescriptor);
_Instance = wgpu.CreateInstance(null);

_Surface = _Window.CreateWebGPUSurface(wgpu, _Instance);

Expand Down Expand Up @@ -116,6 +111,8 @@ private static void WindowOnLoad()

PrintAdapterFeatures();

wgpu.SurfaceGetCapabilities(_Surface, _Adapter, ref _SurfaceCapabilities);

{ //Get device
var deviceDescriptor = new DeviceDescriptor
{
Expand Down Expand Up @@ -155,8 +152,6 @@ private static void WindowOnLoad()
Console.WriteLine($"Created shader {(nuint) _Shader:X}");
} //Load shader

_SwapChainFormat = wgpu.SurfaceGetPreferredFormat(_Surface, _Adapter);

var vertexAttributes = stackalloc VertexAttribute[2];

vertexAttributes[0] = new VertexAttribute
Expand Down Expand Up @@ -397,7 +392,7 @@ private static void WindowOnLoad()

var colorTargetState = new ColorTargetState
{
Format = _SwapChainFormat,
Format = _SurfaceCapabilities.Formats[0],
Blend = &blendState,
WriteMask = ColorWriteMask.All
};
Expand Down Expand Up @@ -513,33 +508,31 @@ private static void UpdateProjectionMatrix()

private static void WindowOnRender(double delta)
{
TextureView* nextTexture = null;

for (var attempt = 0; attempt < 2; attempt++)
SurfaceTexture surfaceTexture;
wgpu.SurfaceGetCurrentTexture(_Surface, &surfaceTexture);
switch (surfaceTexture.Status)
{
nextTexture = wgpu.SwapChainGetCurrentTextureView(_SwapChain);

if (attempt == 0 && nextTexture == null)
{
Console.WriteLine("wgpu.SwapChainGetCurrentTextureView() failed; trying to create a new swap chain...\n");
case SurfaceGetCurrentTextureStatus.Timeout:
case SurfaceGetCurrentTextureStatus.Outdated:
case SurfaceGetCurrentTextureStatus.Lost:
// Recreate swapchain,
wgpu.TextureRelease(surfaceTexture.Texture);
CreateSwapchain();
continue;
}

break;
// Skip this frame
return;
case SurfaceGetCurrentTextureStatus.OutOfMemory:
case SurfaceGetCurrentTextureStatus.DeviceLost:
case SurfaceGetCurrentTextureStatus.Force32:
throw new Exception($"What is going on bros... {surfaceTexture.Status}");
}

if (nextTexture == null)
{
Console.WriteLine("wgpu.SwapChainGetCurrentTextureView() failed after multiple attempts; giving up.\n");
return;
}
var currentTexture = wgpu.TextureCreateView(surfaceTexture.Texture, null);

var encoder = wgpu.DeviceCreateCommandEncoder(_Device, new CommandEncoderDescriptor());

var colorAttachment = new RenderPassColorAttachment
{
View = nextTexture,
View = currentTexture,
ResolveTarget = null,
LoadOp = LoadOp.Clear,
StoreOp = StoreOp.Store,
Expand Down Expand Up @@ -568,15 +561,20 @@ private static void WindowOnRender(double delta)
wgpu.RenderPassEncoderDraw(renderPass, 6, 1, 0, 0);

wgpu.RenderPassEncoderEnd(renderPass);
wgpu.TextureViewRelease(nextTexture);

var queue = wgpu.DeviceGetQueue(_Device);

var commandBuffer = wgpu.CommandEncoderFinish(encoder, new CommandBufferDescriptor());

wgpu.QueueSubmit(queue, 1, &commandBuffer);
wgpu.SwapChainPresent(_SwapChain);
wgpu.SurfacePresent(_Surface);
_Window.SwapBuffers();

wgpu.CommandBufferRelease(commandBuffer);
wgpu.RenderPassEncoderRelease(renderPass);
wgpu.CommandEncoderRelease(encoder);
wgpu.TextureViewRelease(currentTexture);
wgpu.TextureRelease(surfaceTexture.Texture);
}

private static void WindowClosing()
Expand All @@ -599,16 +597,18 @@ private static void FramebufferResize(Vector2D<int> obj)

private static void CreateSwapchain()
{
var swapChainDescriptor = new SwapChainDescriptor
_SurfaceConfiguration = new SurfaceConfiguration
{
Usage = TextureUsage.RenderAttachment,
Format = _SwapChainFormat,
Width = (uint) _Window.FramebufferSize.X,
Height = (uint) _Window.FramebufferSize.Y,
PresentMode = PresentMode.Fifo
Usage = TextureUsage.RenderAttachment,
Device = _Device,
Format = _SurfaceCapabilities.Formats[0],
PresentMode = PresentMode.Fifo,
AlphaMode = _SurfaceCapabilities.AlphaModes[0],
Width = (uint) _Window.FramebufferSize.X,
Height = (uint) _Window.FramebufferSize.Y,
};

_SwapChain = wgpu.DeviceCreateSwapChain(_Device, _Surface, swapChainDescriptor);
wgpu.SurfaceConfigure(_Surface, in _SurfaceConfiguration);
}

private static void PrintAdapterFeatures()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\..\src\WebGPU\Extensions\Silk.NET.WebGPU.Extensions.Disposal\Silk.NET.WebGPU.Extensions.Disposal.csproj" />
<ProjectReference Include="..\..\..\..\src\WebGPU\Silk.NET.WebGPU\Silk.NET.WebGPU.csproj" />
<ProjectReference Include="..\..\..\..\src\Windowing\Silk.NET.GLFW\Silk.NET.GLFW.csproj" />
<ProjectReference Include="..\..\..\..\src\Windowing\Silk.NET.Windowing.Common\Silk.NET.Windowing.Common.csproj" />
Expand Down
74 changes: 37 additions & 37 deletions src/Lab/Experiments/WebGPUTriangle/Program.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using Silk.NET.Core.Native;
using Silk.NET.Maths;
using Silk.NET.WebGPU;
using Silk.NET.WebGPU.Extensions.Disposal;
using Silk.NET.WebGPU.Extensions.WGPU;
using Silk.NET.Windowing;

namespace WebGPUTriangle;
Expand All @@ -15,16 +12,17 @@ public static unsafe class Program
{
// ReSharper disable once InconsistentNaming
private static WebGPU wgpu = null!;
private static IWindow? _Window;
private static IWindow _Window = null!;

private static Surface* _Surface;
private static SurfaceConfiguration _SurfaceConfiguration;
private static SurfaceCapabilities _SurfaceCapabilities;

private static Instance* _Instance;
private static Surface* _Surface;
private static Adapter* _Adapter;
private static Device* _Device;
private static ShaderModule* _Shader;
private static RenderPipeline* _Pipeline;
private static SwapChain* _SwapChain;
private static TextureFormat _SwapChainFormat;

private const string SHADER = @"@vertex
fn vs_main(@builtin(vertex_index) in_vertex_index: u32) -> @builtin(position) vec4<f32> {
Expand Down Expand Up @@ -135,7 +133,7 @@ private static void WindowOnLoad()
Console.WriteLine($"Created shader {(nuint) _Shader:X}");
} //Load shader

_SwapChainFormat = wgpu.SurfaceGetPreferredFormat(_Surface, _Adapter);
wgpu.SurfaceGetCapabilities(_Surface, _Adapter, ref _SurfaceCapabilities);

{ //Create pipeline
var blendState = new BlendState
Expand All @@ -156,7 +154,7 @@ private static void WindowOnLoad()

var colorTargetState = new ColorTargetState
{
Format = _SwapChainFormat,
Format = _SurfaceCapabilities.Formats[0],
Blend = &blendState,
WriteMask = ColorWriteMask.All
};
Expand Down Expand Up @@ -215,51 +213,50 @@ private static void WindowClosing()

private static void CreateSwapchain()
{
var swapChainDescriptor = new SwapChainDescriptor
_SurfaceConfiguration = new SurfaceConfiguration
{
Usage = TextureUsage.RenderAttachment,
Format = _SwapChainFormat,
Width = (uint) _Window.FramebufferSize.X,
Height = (uint) _Window.FramebufferSize.Y,
PresentMode = PresentMode.Fifo
Usage = TextureUsage.RenderAttachment,
Format = _SurfaceCapabilities.Formats[0],
PresentMode = PresentMode.Fifo,
Device = _Device,
Width = (uint)_Window.FramebufferSize.X,
Height = (uint)_Window.FramebufferSize.Y
};

_SwapChain = wgpu.DeviceCreateSwapChain(_Device, _Surface, swapChainDescriptor);
wgpu.SurfaceConfigure(_Surface, _SurfaceConfiguration);
}

private static void WindowOnUpdate(double delta) {}

private static void WindowOnRender(double delta)
{
TextureView* nextTexture = null;

for (var attempt = 0; attempt < 2; attempt++)
SurfaceTexture surfaceTexture;
wgpu.SurfaceGetCurrentTexture(_Surface, &surfaceTexture);
switch (surfaceTexture.Status)
{
nextTexture = wgpu.SwapChainGetCurrentTextureView(_SwapChain);

if (attempt == 0 && nextTexture == null)
{
Console.WriteLine("wgpu.SwapChainGetCurrentTextureView() failed; trying to create a new swap chain...\n");
case SurfaceGetCurrentTextureStatus.Timeout:
case SurfaceGetCurrentTextureStatus.Outdated:
case SurfaceGetCurrentTextureStatus.Lost:
// Recreate swapchain,
wgpu.TextureRelease(surfaceTexture.Texture);
CreateSwapchain();
continue;
}

break;
// Skip this frame
return;
case SurfaceGetCurrentTextureStatus.OutOfMemory:
case SurfaceGetCurrentTextureStatus.DeviceLost:
case SurfaceGetCurrentTextureStatus.Force32:
throw new Exception($"What is going on bros... {surfaceTexture.Status}");
}

if (nextTexture == null)
{
Console.WriteLine("wgpu.SwapChainGetCurrentTextureView() failed after multiple attempts; giving up.\n");
return;
}
var view = wgpu.TextureCreateView(surfaceTexture.Texture, null);

var commandEncoderDescriptor = new CommandEncoderDescriptor();

var encoder = wgpu.DeviceCreateCommandEncoder(_Device, commandEncoderDescriptor);

var colorAttachment = new RenderPassColorAttachment
{
View = nextTexture,
View = view,
ResolveTarget = null,
LoadOp = LoadOp.Clear,
StoreOp = StoreOp.Store,
Expand All @@ -284,15 +281,18 @@ private static void WindowOnRender(double delta)
wgpu.RenderPassEncoderSetPipeline(renderPass, _Pipeline);
wgpu.RenderPassEncoderDraw(renderPass, 3, 1, 0, 0);
wgpu.RenderPassEncoderEnd(renderPass);
wgpu.TextureViewRelease(nextTexture);

var queue = wgpu.DeviceGetQueue(_Device);

var commandBuffer = wgpu.CommandEncoderFinish(encoder, new CommandBufferDescriptor());

wgpu.QueueSubmit(queue, 1, &commandBuffer);
wgpu.SwapChainPresent(_SwapChain);
// _Window.SwapBuffers();
wgpu.SurfacePresent(_Surface);
wgpu.CommandBufferRelease(commandBuffer);
wgpu.RenderPassEncoderRelease(renderPass);
wgpu.CommandEncoderRelease(encoder);
wgpu.TextureViewRelease(view);
wgpu.TextureRelease(surfaceTexture.Texture);
}

private static void PrintAdapterFeatures()
Expand Down
1 change: 0 additions & 1 deletion src/Lab/Experiments/WebGPUTriangle/WebGPUTriangle.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\WebGPU\Extensions\Silk.NET.WebGPU.Extensions.Disposal\Silk.NET.WebGPU.Extensions.Disposal.csproj" />
<ProjectReference Include="..\..\..\WebGPU\Extensions\Silk.NET.WebGPU.Extensions.WGPU\Silk.NET.WebGPU.Extensions.WGPU.csproj" />
<ProjectReference Include="..\..\..\WebGPU\Silk.NET.WebGPU\Silk.NET.WebGPU.csproj" />
<ProjectReference Include="..\..\..\Windowing\Extensions\Silk.NET.Windowing.Extensions\Silk.NET.Windowing.Extensions.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,6 @@ public void Dispose(QuerySet* querySet)
_webGpu.QuerySetRelease(querySet);
}

public void Dispose(SwapChain* swapChain)
{
_webGpu.SwapChainRelease(swapChain);
}

public void Dispose(RenderBundleEncoder* renderBundleEncoder)
{
_webGpu.RenderBundleEncoderRelease(renderBundleEncoder);
Expand Down

0 comments on commit 630529f

Please sign in to comment.