diff --git a/src/Lab/Experiments/WebGPUTexturedQuad/Program.cs b/src/Lab/Experiments/WebGPUTexturedQuad/Program.cs index 488bb206c0..d7a897f9ce 100644 --- a/src/Lab/Experiments/WebGPUTexturedQuad/Program.cs +++ b/src/Lab/Experiments/WebGPUTexturedQuad/Program.cs @@ -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; @@ -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; @@ -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); @@ -116,6 +111,8 @@ private static void WindowOnLoad() PrintAdapterFeatures(); + wgpu.SurfaceGetCapabilities(_Surface, _Adapter, ref _SurfaceCapabilities); + { //Get device var deviceDescriptor = new DeviceDescriptor { @@ -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 @@ -397,7 +392,7 @@ private static void WindowOnLoad() var colorTargetState = new ColorTargetState { - Format = _SwapChainFormat, + Format = _SurfaceCapabilities.Formats[0], Blend = &blendState, WriteMask = ColorWriteMask.All }; @@ -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, @@ -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() @@ -599,16 +597,18 @@ private static void FramebufferResize(Vector2D 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() diff --git a/src/Lab/Experiments/WebGPUTexturedQuad/WebGPUTexturedQuad.csproj b/src/Lab/Experiments/WebGPUTexturedQuad/WebGPUTexturedQuad.csproj index 1e1ec8d176..1fd99ba2b9 100644 --- a/src/Lab/Experiments/WebGPUTexturedQuad/WebGPUTexturedQuad.csproj +++ b/src/Lab/Experiments/WebGPUTexturedQuad/WebGPUTexturedQuad.csproj @@ -11,7 +11,6 @@ - diff --git a/src/Lab/Experiments/WebGPUTriangle/Program.cs b/src/Lab/Experiments/WebGPUTriangle/Program.cs index bb5ecf75d5..20d15da118 100644 --- a/src/Lab/Experiments/WebGPUTriangle/Program.cs +++ b/src/Lab/Experiments/WebGPUTriangle/Program.cs @@ -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; @@ -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 { @@ -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 @@ -156,7 +154,7 @@ private static void WindowOnLoad() var colorTargetState = new ColorTargetState { - Format = _SwapChainFormat, + Format = _SurfaceCapabilities.Formats[0], Blend = &blendState, WriteMask = ColorWriteMask.All }; @@ -215,43 +213,42 @@ 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(); @@ -259,7 +256,7 @@ private static void WindowOnRender(double delta) var colorAttachment = new RenderPassColorAttachment { - View = nextTexture, + View = view, ResolveTarget = null, LoadOp = LoadOp.Clear, StoreOp = StoreOp.Store, @@ -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() diff --git a/src/Lab/Experiments/WebGPUTriangle/WebGPUTriangle.csproj b/src/Lab/Experiments/WebGPUTriangle/WebGPUTriangle.csproj index 23f573a217..22b4c1358e 100644 --- a/src/Lab/Experiments/WebGPUTriangle/WebGPUTriangle.csproj +++ b/src/Lab/Experiments/WebGPUTriangle/WebGPUTriangle.csproj @@ -9,7 +9,6 @@ - diff --git a/src/WebGPU/Extensions/Silk.NET.WebGPU.Extensions.Disposal/WebGPUDisposal.cs b/src/WebGPU/Extensions/Silk.NET.WebGPU.Extensions.Disposal/WebGPUDisposal.cs index 3b8c1b8adb..e66c1f36fa 100644 --- a/src/WebGPU/Extensions/Silk.NET.WebGPU.Extensions.Disposal/WebGPUDisposal.cs +++ b/src/WebGPU/Extensions/Silk.NET.WebGPU.Extensions.Disposal/WebGPUDisposal.cs @@ -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);