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.<InitLookup>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()
This commit is contained in:
AsperTheDog 2026-05-17 23:22:28 +02:00
parent 48a238a5cb
commit 081ca1c340

View file

@ -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<DisposableBuffer>[] autos = ArrayPool<Auto<DisposableBuffer>>.Shared.Rent(count);
Span<int> getOffsets = stackalloc int[Constants.MaxVertexBuffers];
Span<int> getSizes = stackalloc int[Constants.MaxVertexBuffers];
Span<ulong> offsets = stackalloc ulong[Constants.MaxVertexBuffers];
Span<ulong> sizes = stackalloc ulong[Constants.MaxVertexBuffers];
Span<ulong> strides = stackalloc ulong[Constants.MaxVertexBuffers];
Span<VkBuffer> 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<Auto<DisposableBuffer>>.Shared.Return(autos, clearArray: true);
}
}
}