Initialize WebGPU
This commit is contained in:
@@ -124,7 +124,7 @@ namespace Voile.Audio
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
private FMOD.System _system;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user