Initialize WebGPU

This commit is contained in:
2024-08-18 19:53:31 +02:00
parent f64510fbd2
commit b40af1200a
4 changed files with 208 additions and 95 deletions

View File

@@ -124,7 +124,7 @@ namespace Voile.Audio
public override void Shutdown()
{
throw new NotImplementedException();
}
private FMOD.System _system;

View File

@@ -1,20 +1,22 @@
using System.Drawing;
using System.Numerics;
using Silk.NET.GLFW;
using Silk.NET.OpenGL;
using Silk.NET.Windowing;
using Silk.NET.WebGPU;
using Silk.NET.Maths;
using Voile.Utils;
using System.Runtime.InteropServices;
namespace Voile.Rendering
{
/// <summary>
/// A standard, OpenGL-based renderer.
/// A standard, WebGPU-based renderer.
/// </summary>
public class StandardRenderer : Renderer
{
/// <inheritdoc />
public override Vector2 WindowSize { get; set; }
/// <inheritdoc />
public override bool ShouldRun => throw new NotImplementedException();
public override bool ShouldRun => !_window?.IsClosing ?? false;
public override Vector2 MonitorSize => throw new NotImplementedException();
@@ -23,13 +25,20 @@ namespace Voile.Rendering
public override string WindowTitle { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public override bool Fullscreen { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
/// <inheritdoc />
public override void Initialize(RendererSettings settings)
{
_logger.Info("Initializing WebGPU...");
CreateApi();
CreateInstance();
CreateSurface();
CreateAdapter();
CreateDevice();
ConfigureDebugCallback();
ConfigureSurface();
}
/// <inheritdoc />
@@ -39,31 +48,51 @@ namespace Voile.Rendering
Initialize(renderSettings);
}
public override void BeginFrame()
{
_glfw.PollEvents();
_gl.Viewport(new Size((int)_windowSize.X, (int)_windowSize.Y));
}
/// <inheritdoc />
public override void EndFrame()
public override void CreateWindow(WindowSettings windowSettings)
{
// throw new NotImplementedException();
EndFrameUnsafe();
_logger.Info("Creating window...");
WindowOptions windowOptions = WindowOptions.Default;
windowOptions.Size = new Vector2D<int>((int)windowSettings.Size.X, (int)windowSettings.Size.Y);
windowOptions.Title = windowSettings.Title;
windowOptions.API = GraphicsAPI.None;
_window = Window.Create(windowOptions);
_window.Initialize();
}
public override void BeginFrame()
{
_window!.DoEvents();
_window.DoUpdate();
_window.DoRender();
}
/// <inheritdoc />
public override void ClearBackground(Color color)
{
_gl.ClearColor(color.ToSystemColor());
_gl.Clear((uint)ClearBufferMask.ColorBufferBit);
throw new NotImplementedException();
}
/// <inheritdoc />
public override void Shutdown()
public override void DrawText(Font font, string text, Color color)
{
CloseWindowUnsafe();
_glfw.Terminate();
throw new NotImplementedException();
}
public override void DrawSdfText(string text, int fontSize, Color color)
{
throw new NotImplementedException();
}
public override void BeginCamera2d(Vector2 offset, Vector2 target, float rotation, float zoom)
{
throw new NotImplementedException();
}
public override void EndCamera2d()
{
throw new NotImplementedException();
}
/// <inheritdoc />
@@ -90,6 +119,22 @@ namespace Voile.Rendering
throw new NotImplementedException();
}
/// <inheritdoc />
public override void EndFrame()
{
}
/// <inheritdoc />
public override void Shutdown()
{
_window!.DoEvents();
_window.Reset();
_window.Dispose();
ShutdownUnsafe();
}
/// <inheritdoc />
protected override double GetFrameTime()
{
@@ -111,7 +156,7 @@ namespace Voile.Rendering
/// <inheritdoc />
protected override void SetWindowTitle(string title)
{
SetWindowTitleUnsafe(title);
throw new NotImplementedException();
}
/// <inheritdoc />
@@ -121,50 +166,7 @@ namespace Voile.Rendering
}
/// <inheritdoc />
protected override bool WindowShouldClose() => WindowShouldCloseUnsafe();
private unsafe void CreateWindowUnsafe(string title, Vector2 size)
{
_glfw = GlfwProvider.GLFW.Value;
_glfw.Init();
_glfw.WindowHint(WindowHintInt.ContextVersionMajor, 4);
_glfw.WindowHint(WindowHintInt.ContextVersionMinor, 6);
_windowHandle = _glfw.CreateWindow((int)size.X, (int)size.Y, title, null, null);
_glfw.MakeContextCurrent(_windowHandle);
_gl = GL.GetApi(_glfw.GetProcAddress);
_glfw.SwapInterval(1);
_windowSize = size;
}
private unsafe void CloseWindowUnsafe() => _glfw.DestroyWindow(_windowHandle);
private unsafe bool WindowShouldCloseUnsafe() => _glfw.WindowShouldClose(_windowHandle);
private unsafe void SetWindowTitleUnsafe(string title) => _glfw.SetWindowTitle(_windowHandle, title);
private unsafe void EndFrameUnsafe()
{
_glfw.SwapBuffers(_windowHandle);
}
public override void DrawSdfText(string text, int fontSize, Color color)
{
throw new NotImplementedException();
}
public override void BeginCamera2d(Vector2 offset, Vector2 target, float rotation, float zoom)
{
throw new NotImplementedException();
}
public override void EndCamera2d()
{
throw new NotImplementedException();
}
public override void CreateWindow(WindowSettings windowSettings)
{
throw new NotImplementedException();
}
protected override bool WindowShouldClose() => throw new NotImplementedException();
protected override int GetMonitorWidth(int monitorId)
{
@@ -181,14 +183,120 @@ namespace Voile.Rendering
throw new NotImplementedException();
}
public override void DrawText(Font font, string text, Color color)
private unsafe void CreateApi()
{
throw new NotImplementedException();
_wgpu = WebGPU.GetApi();
}
private unsafe void CreateInstance()
{
InstanceDescriptor descriptor = new();
_instance = _wgpu!.CreateInstance(descriptor);
}
private unsafe void CreateSurface()
{
_surface = _window.CreateWebGPUSurface(_wgpu, _instance);
}
private unsafe void CreateAdapter()
{
RequestAdapterOptions adapterOptions = new()
{
CompatibleSurface = _surface,
// TODO: do not force Vulkan, let user choose their own API.
BackendType = BackendType.Vulkan,
PowerPreference = PowerPreference.HighPerformance
};
PfnRequestAdapterCallback callback = PfnRequestAdapterCallback.From(
(status, adapter, msgPtr, userDataPtr) =>
{
if (status == RequestAdapterStatus.Success)
{
_adapter = adapter;
AdapterProperties adapterProperties = new();
_wgpu.AdapterGetProperties(_adapter, &adapterProperties);
string deviceName = Marshal.PtrToStringAnsi((IntPtr)adapterProperties.Name);
_logger.Info($"Retrieved WebGPU Adapter ({deviceName})");
}
else
{
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
_logger.Error($"Error while retrieving WebGPU Adapter: {msg}");
}
});
_wgpu.InstanceRequestAdapter(_instance, adapterOptions, callback, null);
}
private unsafe void CreateDevice()
{
DeviceDescriptor deviceDescriptor = new();
PfnRequestDeviceCallback callback = PfnRequestDeviceCallback.From(
(status, device, msgPtr, userDataPtr) =>
{
if (status == RequestDeviceStatus.Success)
{
_device = device;
_logger.Info($"Retrieved WebGPU Device.");
}
else
{
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
_logger.Error($"Error while retrieving WebGPU Device: {msg}");
}
});
_wgpu.AdapterRequestDevice(_adapter, deviceDescriptor, callback, null);
}
private unsafe void ConfigureSurface()
{
SurfaceConfiguration configuration = new SurfaceConfiguration();
configuration.Device = _device;
configuration.Width = (uint)_window!.Size.X;
configuration.Height = (uint)_window.Size.Y;
configuration.Format = Silk.NET.WebGPU.TextureFormat.Bgra8Unorm;
configuration.PresentMode = PresentMode.Fifo;
_wgpu!.SurfaceConfigure(_surface, configuration);
}
private unsafe void ConfigureDebugCallback()
{
PfnErrorCallback callback = PfnErrorCallback.From((type, msgPtr, userDataPtr) =>
{
string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr);
_logger.Error($"WebGPU Error: {msg}");
});
_wgpu.DeviceSetUncapturedErrorCallback(_device, callback, null);
_logger.Info("WGPU Debug Callback Configured.");
}
private unsafe void ShutdownUnsafe()
{
_wgpu.DeviceDestroy(_device);
_wgpu.InstanceRelease(_instance);
_wgpu.SurfaceRelease(_surface);
_wgpu.AdapterRelease(_adapter);
}
private GL _gl;
private Glfw _glfw;
private unsafe WindowHandle* _windowHandle;
private Vector2 _windowSize;
private IWindow? _window;
private WebGPU? _wgpu;
private unsafe Instance* _instance;
private unsafe Surface* _surface;
private unsafe Adapter* _adapter;
private unsafe Device* _device;
private Logger _logger = new(nameof(StandardRenderer));
}
}

View File

@@ -9,11 +9,13 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Silk.NET.WebGPU" Version="2.20.0" />
<PackageReference Include="Silk.NET.WebGPU.Native.WGPU" Version="2.20.0" />
<PackageReference Include="Silk.NET.Windowing" Version="2.20.0" />
<PackageReference Include="Voile.Fmod" Version="0.2.2.8" />
<PackageReference Include="ImGui.NET" Version="1.89.4" />
<PackageReference Include="Raylib-cs" Version="4.2.0.1" />
<PackageReference Include="SharpFont" Version="4.0.1" />
<PackageReference Include="Silk.NET" Version="2.17.0" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta19" />
<PackageReference Include="StbImageSharp" Version="2.27.13" />
<PackageReference Include="StbVorbisSharp" Version="1.22.4" />