revert: restore state before huge regression

This commit is contained in:
ParantezTech
2026-07-23 16:03:45 +03:00
parent 5a08a9bb43
commit 6db095ec82
39 changed files with 230 additions and 4186 deletions
@@ -18,7 +18,6 @@ internal readonly record struct VulkanHostBufferAllocation(
internal sealed class VulkanHostBufferPool : IDisposable
{
private readonly object _gate = new();
private readonly Dictionary<VulkanHostBufferPoolKey, Stack<VulkanHostBufferAllocation>>
_available = [];
private readonly Dictionary<ulong, VulkanHostBufferAllocation> _allocations = [];
@@ -41,19 +40,16 @@ internal sealed class VulkanHostBufferPool : IDisposable
VulkanHostBufferPoolKey key,
out VulkanHostBufferAllocation allocation)
{
lock (_gate)
if (!_available.TryGetValue(key, out var available) ||
!available.TryPop(out allocation))
{
if (!_available.TryGetValue(key, out var available) ||
!available.TryPop(out allocation))
{
allocation = default;
return false;
}
_cachedHandles.Remove(allocation.Buffer.Handle);
CachedBytes -= allocation.Key.Capacity;
return true;
allocation = default;
return false;
}
_cachedHandles.Remove(allocation.Buffer.Handle);
CachedBytes -= allocation.Key.Capacity;
return true;
}
public void Register(VulkanHostBufferAllocation allocation)
@@ -63,79 +59,51 @@ internal sealed class VulkanHostBufferPool : IDisposable
throw new ArgumentException("A pooled buffer must have a valid handle.", nameof(allocation));
}
lock (_gate)
{
_allocations.Add(allocation.Buffer.Handle, allocation);
}
_allocations.Add(allocation.Buffer.Handle, allocation);
}
public bool Return(VkBuffer buffer, DeviceMemory memory)
{
VulkanHostBufferAllocation? toDestroy = null;
lock (_gate)
if (!_allocations.TryGetValue(buffer.Handle, out var allocation) ||
allocation.Memory.Handle != memory.Handle)
{
if (!_allocations.TryGetValue(buffer.Handle, out var allocation) ||
allocation.Memory.Handle != memory.Handle)
{
return false;
}
if (!_cachedHandles.Add(buffer.Handle))
{
return true;
}
if (allocation.Key.Capacity > MaximumCachedBytes - CachedBytes)
{
_cachedHandles.Remove(buffer.Handle);
_allocations.Remove(buffer.Handle);
toDestroy = allocation;
}
else
{
if (!_available.TryGetValue(allocation.Key, out var available))
{
available = [];
_available.Add(allocation.Key, available);
}
available.Push(allocation);
CachedBytes += allocation.Key.Capacity;
}
return false;
}
// Destroy outside the lock — _destroy calls into Vulkan which may
// grab device-level locks, and holding _gate while doing so risks
// a lock-ordering deadlock with a thread that holds the device lock
// and is waiting on _gate.
if (toDestroy is { } td)
{
_destroy(td);
if (!_cachedHandles.Add(buffer.Handle))
{
return true;
}
if (allocation.Key.Capacity > MaximumCachedBytes - CachedBytes)
{
_cachedHandles.Remove(buffer.Handle);
_allocations.Remove(buffer.Handle);
_destroy(allocation);
return true;
}
if (!_available.TryGetValue(allocation.Key, out var available))
{
available = [];
_available.Add(allocation.Key, available);
}
available.Push(allocation);
CachedBytes += allocation.Key.Capacity;
return true;
}
public void Dispose()
{
// Snapshot under the lock, destroy outside — _destroy calls into
// Vulkan which may grab device-level locks; holding _gate while
// doing so risks a lock-ordering deadlock with any thread that
// acquires the device lock first and then waits on _gate.
List<VulkanHostBufferAllocation> toDestroy;
lock (_gate)
{
toDestroy = new List<VulkanHostBufferAllocation>(_allocations.Values);
_allocations.Clear();
_available.Clear();
_cachedHandles.Clear();
CachedBytes = 0;
}
foreach (var allocation in toDestroy)
foreach (var allocation in _allocations.Values)
{
_destroy(allocation);
}
_allocations.Clear();
_available.Clear();
_cachedHandles.Clear();
CachedBytes = 0;
}
}
@@ -3170,7 +3170,6 @@ internal static unsafe class VulkanVideoPresenter
public uint NumberFormat;
public uint Stride;
public uint OffsetBytes;
public bool PerInstance;
}
private const Format DepthFormat = Format.D32Sfloat;
@@ -6659,47 +6658,33 @@ internal static unsafe class VulkanVideoPresenter
PName = entryPoint,
};
// One Vulkan binding per unique host buffer and input rate
// (fetch_index). Attributes share that binding with
// Offset = OffsetBytes.
var bindingByBuffer = new Dictionary<(ulong Handle, bool PerInstance), uint>();
var vertexBindingList = new List<VertexInputBindingDescription>();
var vertexBindingDescriptions =
new VertexInputBindingDescription[resources.VertexBuffers.Length];
var vertexAttributeDescriptions =
new VertexInputAttributeDescription[resources.VertexBuffers.Length];
for (var index = 0; index < resources.VertexBuffers.Length; index++)
{
var vertexBuffer = resources.VertexBuffers[index];
var bufferKey = (vertexBuffer.Buffer.Handle, vertexBuffer.PerInstance);
if (!bindingByBuffer.TryGetValue(bufferKey, out var bindingIndex))
vertexBindingDescriptions[index] = new VertexInputBindingDescription
{
bindingIndex = (uint)vertexBindingList.Count;
bindingByBuffer[bufferKey] = bindingIndex;
vertexBindingList.Add(new VertexInputBindingDescription
{
Binding = bindingIndex,
Stride = vertexBuffer.Stride == 0
? Math.Max(vertexBuffer.ComponentCount, 1) * sizeof(float)
: vertexBuffer.Stride,
InputRate = vertexBuffer.PerInstance
? VertexInputRate.Instance
: VertexInputRate.Vertex,
});
}
Binding = (uint)index,
Stride = vertexBuffer.Stride == 0
? Math.Max(vertexBuffer.ComponentCount, 1) * sizeof(float)
: vertexBuffer.Stride,
InputRate = VertexInputRate.Vertex,
};
vertexAttributeDescriptions[index] = new VertexInputAttributeDescription
{
Location = vertexBuffer.Location,
Binding = bindingIndex,
Binding = (uint)index,
Format = ToVkVertexFormat(
vertexBuffer.DataFormat,
vertexBuffer.NumberFormat,
vertexBuffer.ComponentCount),
Offset = vertexBuffer.OffsetBytes,
Offset = 0,
};
}
var vertexBindingDescriptions = vertexBindingList.ToArray();
fixed (VertexInputBindingDescription* vertexBindingPointerBase = vertexBindingDescriptions)
fixed (VertexInputAttributeDescription* vertexAttributePointerBase = vertexAttributeDescriptions)
{
@@ -9295,7 +9280,6 @@ internal static unsafe class VulkanVideoPresenter
NumberFormat = guestBuffer.NumberFormat,
Stride = guestBuffer.Stride,
OffsetBytes = guestBuffer.OffsetBytes,
PerInstance = guestBuffer.PerInstance,
};
}
@@ -9313,7 +9297,6 @@ internal static unsafe class VulkanVideoPresenter
NumberFormat = guestBuffer.NumberFormat,
Stride = guestBuffer.Stride,
OffsetBytes = guestBuffer.OffsetBytes,
PerInstance = guestBuffer.PerInstance,
};
private VkBuffer CreateHostBuffer(
@@ -9415,28 +9398,21 @@ internal static unsafe class VulkanVideoPresenter
private static Format ToVkVertexFormat(
uint dataFormat,
uint numberFormat,
uint componentCount)
{
var format = (dataFormat, numberFormat) switch
uint componentCount) =>
(dataFormat, numberFormat) switch
{
(1, 0) => Format.R8Unorm,
(1, 1) => Format.R8SNorm,
(1, 2) => Format.R8Uscaled,
(1, 3) => Format.R8Sscaled,
(1, 4) => Format.R8Uint,
(1, 5) => Format.R8Sint,
(1, 9) => Format.R8Srgb,
(2, 0) => Format.R16Unorm,
(2, 1) => Format.R16SNorm,
(2, 2) => Format.R16Uscaled,
(2, 3) => Format.R16Sscaled,
(2, 4) => Format.R16Uint,
(2, 5) => Format.R16Sint,
(2, 7) => Format.R16Sfloat,
(3, 0) => Format.R8G8Unorm,
(3, 1) => Format.R8G8SNorm,
(3, 2) => Format.R8G8Uscaled,
(3, 3) => Format.R8G8Sscaled,
(3, 4) => Format.R8G8Uint,
(3, 5) => Format.R8G8Sint,
(3, 9) => Format.R8G8Srgb,
@@ -9491,9 +9467,6 @@ internal static unsafe class VulkanVideoPresenter
(14, 4) => Format.R32G32B32A32Uint,
(14, 5) => Format.R32G32B32A32Sint,
(14, 7) => Format.R32G32B32A32Sfloat,
// Prospero VertexAttribFormat quirks also seen as buffer formats.
(113, _) => Format.R32G32B32A32Sfloat,
(121, _) => Format.R16G16Sfloat,
(16, 0) => Format.B5G6R5UnormPack16,
(17, 0) => Format.R5G5B5A1UnormPack16,
(19, 0) => Format.R4G4B4A4UnormPack16,
@@ -9501,38 +9474,6 @@ internal static unsafe class VulkanVideoPresenter
_ => ToVkFloatVertexFormat(componentCount),
};
return NarrowVkVertexFormat(format, componentCount);
}
/// <summary>
/// Narrow a sharp's full VkFormat to the component count the VS fetch
/// actually consumes.
/// </summary>
private static Format NarrowVkVertexFormat(Format format, uint usedComponents)
{
if (usedComponents == 0)
{
return format;
}
return (format, usedComponents) switch
{
(Format.R32G32B32A32Sfloat, 1) => Format.R32Sfloat,
(Format.R32G32B32A32Sfloat, 2) => Format.R32G32Sfloat,
(Format.R32G32B32A32Sfloat, 3) => Format.R32G32B32Sfloat,
(Format.R32G32B32Sfloat, 1) => Format.R32Sfloat,
(Format.R32G32B32Sfloat, 2) => Format.R32G32Sfloat,
(Format.R16G16B16A16Sfloat, 1) => Format.R16Sfloat,
(Format.R16G16B16A16Sfloat, 2) => Format.R16G16Sfloat,
(Format.R8G8B8A8Unorm, 1) => Format.R8Unorm,
(Format.R8G8B8A8Unorm, 2) => Format.R8G8Unorm,
(Format.R8G8B8A8SNorm, 2) => Format.R8G8SNorm,
(Format.R8G8B8A8Uint, 1) => Format.R8Uint,
(Format.R8G8B8A8Uint, 2) => Format.R8G8Uint,
_ => format,
};
}
private static Format ToVkFloatVertexFormat(uint componentCount) =>
componentCount switch
{