From 081ca1c340ceecf53cf5c181b83c2bdde1be46b2 Mon Sep 17 00:00:00 2001 From: AsperTheDog Date: Sun, 17 May 2026 23:22:28 +0200 Subject: [PATCH] WIP: Potential fix. Needs testing |E| GUI.RenderThread Application : Unhandled exception caught: System.NullReferenceException: Object reference not set to an instance of an object. at Ryujinx.Graphics.Vulkan.VertexBufferUpdater.Commit(CommandBufferScoped cbs) in /workspace/projects/Ryubing/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs:line 66 at Ryujinx.Graphics.Vulkan.PipelineBase.Rebind(Auto`1 buffer, Int32 offset, Int32 size) in /workspace/projects/Ryubing/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs:line 701 at Ryujinx.Graphics.Vulkan.VertexBufferUpdater.Commit(CommandBufferScoped cbs) in /workspace/projects/Ryubing/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs:line 66 at Ryujinx.Graphics.Vulkan.PipelineBase.RecreateGraphicsPipelineIfNeeded() in /workspace/projects/Ryubing/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs:line 1652 at Ryujinx.Graphics.GAL.Multithreading.CommandHelper.<>c.b__5_1[T](Span`1 memory, ThreadedRenderer threaded, IRenderer renderer) in /workspace/projects/Ryubing/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs:line 43 at Ryujinx.Graphics.GAL.Multithreading.ThreadedRenderer.RenderLoop() in /workspace/projects/Ryubing/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs:line 146 at Ryujinx.Graphics.GAL.Multithreading.ThreadedRenderer.RunLoop(ThreadStart gpuLoop) in /workspace/projects/Ryubing/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs:line 115 at Ryujinx.Ava.Systems.AppHost.RenderLoop() in /workspace/projects/Ryubing/src/Ryujinx/Systems/AppHost.cs:line 1096 at System.Threading.Thread.StartCallback() --- .../VertexBufferUpdater.cs | 81 ++++++++++++++----- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs b/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs index 8927d2264..c2c2ba6f2 100644 --- a/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/VertexBufferUpdater.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers; using VkBuffer = Silk.NET.Vulkan.Buffer; namespace Ryujinx.Graphics.Vulkan @@ -61,29 +62,65 @@ namespace Ryujinx.Graphics.Vulkan { if (_count != 0) { - for (int i = 0; i < _count; i++) - { - _buffers[i] = _bufferAutos[i].Get(cbs, _bufferOffsetsForGet[i], _bufferSizesForGet[i]).Value; - _bufferAutos[i] = null; - } - - if (_gd.Capabilities.SupportsExtendedDynamicState) - { - _gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2( - cbs.CommandBuffer, - _baseBinding, - _count, - _buffers.Pointer, - _offsets.Pointer, - _sizes.Pointer, - _strides.Pointer); - } - else - { - _gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, _baseBinding, _count, _buffers.Pointer, _offsets.Pointer); - } - + int count = (int)_count; + uint baseBinding = _baseBinding; _count = 0; + + Auto[] autos = ArrayPool>.Shared.Rent(count); + Span getOffsets = stackalloc int[Constants.MaxVertexBuffers]; + Span getSizes = stackalloc int[Constants.MaxVertexBuffers]; + Span offsets = stackalloc ulong[Constants.MaxVertexBuffers]; + Span sizes = stackalloc ulong[Constants.MaxVertexBuffers]; + Span strides = stackalloc ulong[Constants.MaxVertexBuffers]; + Span buffers = stackalloc VkBuffer[Constants.MaxVertexBuffers]; + + for (int i = 0; i < count; i++) + { + autos[i] = _bufferAutos[i]; + _bufferAutos[i] = null; + getOffsets[i] = _bufferOffsetsForGet[i]; + getSizes[i] = _bufferSizesForGet[i]; + offsets[i] = _offsets[i]; + sizes[i] = _sizes[i]; + strides[i] = _strides[i]; + } + + try + { + for (int i = 0; i < count; i++) + { + buffers[i] = autos[i].Get(cbs, getOffsets[i], getSizes[i]).Value; + autos[i] = null; + } + + for (int i = 0; i < count; i++) + { + _buffers[i] = buffers[i]; + _offsets[i] = offsets[i]; + _sizes[i] = sizes[i]; + _strides[i] = strides[i]; + } + + if (_gd.Capabilities.SupportsExtendedDynamicState) + { + _gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2( + cbs.CommandBuffer, + baseBinding, + (uint)count, + _buffers.Pointer, + _offsets.Pointer, + _sizes.Pointer, + _strides.Pointer); + } + else + { + _gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, baseBinding, (uint)count, _buffers.Pointer, _offsets.Pointer); + } + } + finally + { + ArrayPool>.Shared.Return(autos, clearArray: true); + } } }