[Gpu] Migrate Vk buffer barriers to synchronization2

This commit is contained in:
ParantezTech 2026-09-22 15:58:49 +03:00
parent 43315e9b7a
commit e7c9dca969
3 changed files with 29 additions and 26 deletions

View File

@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
using SharpEmu.HLE.GpuMemory;
using SharpEmu.Libs.Gpu.Scheduling;
using SharpEmu.ShaderCompiler.Vulkan;
using SharpEmu.Libs.Gpu.Vulkan;
using Silk.NET.Vulkan;
namespace SharpEmu.Libs.Gpu.Buffers;
@ -191,11 +192,11 @@ public sealed unsafe class BdaFaultProcessor : IDisposable
_downloadBuffer.Mapped.Slice((int)offset, (int)PageFaultAreaSize).Clear();
_downloadBuffer.Flush(offset, PageFaultAreaSize);
var preBarrier = new BufferMemoryBarrier
var preBarrier = new BufferMemoryBarrier2
{
SType = StructureType.BufferMemoryBarrier,
SrcAccessMask = AccessFlags.ShaderWriteBit,
DstAccessMask = AccessFlags.ShaderReadBit,
SType = StructureType.BufferMemoryBarrier2,
SrcAccessMask = AccessFlags2.ShaderWriteBit,
DstAccessMask = AccessFlags2.ShaderReadBit,
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
Buffer = _faultBuffer.Handle,
@ -203,12 +204,12 @@ public sealed unsafe class BdaFaultProcessor : IDisposable
Size = _faultBufferSize,
};
var postBarrier = preBarrier;
postBarrier.DstAccessMask = AccessFlags.ShaderWriteBit;
postBarrier.DstAccessMask = AccessFlags2.ShaderWriteBit;
_scheduler.EndRendering();
var vk = _device.Vk;
var command = new CommandBuffer(_scheduler.Current.Handle);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
command, PipelineStageFlags.AllCommandsBit, PipelineStageFlags.ComputeShaderBit, DependencyFlags.ByRegionBit,
0, null, 1, &preBarrier, 0, null);
vk.CmdBindPipeline(command, PipelineBindPoint.Compute, _pipeline);
@ -216,7 +217,7 @@ public sealed unsafe class BdaFaultProcessor : IDisposable
vk.CmdBindDescriptorSets(command, PipelineBindPoint.Compute, _pipelineLayout, 0, 1, &set, 0, null);
var threads = _pageCount / 32;
vk.CmdDispatch(command, (uint)((threads + 63) / 64), 1, 1);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
command, PipelineStageFlags.ComputeShaderBit, PipelineStageFlags.AllCommandsBit, DependencyFlags.ByRegionBit,
0, null, 1, &postBarrier, 0, null);

View File

@ -3,6 +3,7 @@
using System.Numerics;
using SharpEmu.Libs.Gpu.Scheduling;
using SharpEmu.Libs.Gpu.Vulkan;
using Silk.NET.Vulkan;
using VkBuffer = Silk.NET.Vulkan.Buffer;
@ -190,18 +191,18 @@ public unsafe class GpuBuffer : IDisposable
command.EndRendering();
var vk = _device.Vk;
var native = new CommandBuffer(command.Handle);
var before = stackalloc BufferMemoryBarrier[2];
var before = stackalloc BufferMemoryBarrier2[2];
before[0] = source.CreateBarrier(sourceOffset, size, sourceBefore, AccessFlags.TransferReadBit);
before[1] = CreateBarrier(destinationOffset, size, destinationBefore, AccessFlags.TransferWriteBit);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
native, GetAccessStage(sourceBefore | destinationBefore), PipelineStageFlags.TransferBit, DependencyFlags.ByRegionBit,
0, null, 2, before, 0, null);
var copy = new BufferCopy(sourceOffset, destinationOffset, size);
vk.CmdCopyBuffer(native, source.Handle, Handle, 1, &copy);
var after = stackalloc BufferMemoryBarrier[2];
var after = stackalloc BufferMemoryBarrier2[2];
after[0] = source.CreateBarrier(sourceOffset, size, AccessFlags.TransferReadBit, sourceAfter);
after[1] = CreateBarrier(destinationOffset, size, AccessFlags.TransferWriteBit, destinationAfter);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
native, PipelineStageFlags.TransferBit, GetAccessStage(sourceAfter | destinationAfter), DependencyFlags.ByRegionBit,
0, null, 2, after, 0, null);
}
@ -218,12 +219,12 @@ public unsafe class GpuBuffer : IDisposable
var vk = _device.Vk;
var native = new CommandBuffer(command.Handle);
var before = CreateBarrier(offset, size, MemoryAccess, AccessFlags.TransferWriteBit);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
native, PipelineStageFlags.AllCommandsBit, PipelineStageFlags.TransferBit, DependencyFlags.ByRegionBit,
0, null, 1, &before, 0, null);
vk.CmdFillBuffer(native, Handle, offset, size, value);
var after = CreateBarrier(offset, size, AccessFlags.TransferWriteBit, MemoryAccess);
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
native, PipelineStageFlags.TransferBit, PipelineStageFlags.AllCommandsBit, DependencyFlags.ByRegionBit,
0, null, 1, &after, 0, null);
}
@ -284,7 +285,7 @@ public unsafe class GpuBuffer : IDisposable
};
}
private BufferMemoryBarrier CreateBarrier(ulong offset, ulong size, AccessFlags source, AccessFlags destination)
private BufferMemoryBarrier2 CreateBarrier(ulong offset, ulong size, AccessFlags source, AccessFlags destination)
{
if (Handle.Handle == 0 || size == 0 || offset > Size || size > Size - offset)
{
@ -292,11 +293,11 @@ public unsafe class GpuBuffer : IDisposable
$"The DMA barrier range is invalid: handle=0x{Handle.Handle:X} offset=0x{offset:X16} size=0x{size:X16} capacity=0x{Size:X16}");
}
return new BufferMemoryBarrier
return new BufferMemoryBarrier2
{
SType = StructureType.BufferMemoryBarrier,
SrcAccessMask = source,
DstAccessMask = destination,
SType = StructureType.BufferMemoryBarrier2,
SrcAccessMask = VulkanSynchronization.Access(source),
DstAccessMask = VulkanSynchronization.Access(destination),
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
Buffer = Handle,

View File

@ -8,6 +8,7 @@ using SharpEmu.HLE.GuestMemory;
using SharpEmu.Libs.Gpu.Scheduling;
using SharpEmu.Libs.Kernel;
using SharpEmu.Libs.VideoOut;
using SharpEmu.Libs.Gpu.Vulkan;
using Silk.NET.Vulkan;
namespace SharpEmu.Libs.Gpu.Buffers;
@ -1014,18 +1015,18 @@ public sealed unsafe class GuestBufferCache : IGuestBufferStore, IDisposable
command.EndRendering();
var native = new CommandBuffer(command.Handle);
var vk = _device.Vk;
var before = new BufferMemoryBarrier
var before = new BufferMemoryBarrier2
{
SType = StructureType.BufferMemoryBarrier,
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit | AccessFlags.TransferReadBit | AccessFlags.TransferWriteBit,
DstAccessMask = AccessFlags.TransferWriteBit,
SType = StructureType.BufferMemoryBarrier2,
SrcAccessMask = AccessFlags2.MemoryReadBit | AccessFlags2.MemoryWriteBit | AccessFlags2.TransferReadBit | AccessFlags2.TransferWriteBit,
DstAccessMask = AccessFlags2.TransferWriteBit,
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
Buffer = buffer.Handle,
Offset = 0,
Size = buffer.Size,
};
vk.CmdPipelineBarrier(
VulkanSynchronization.PipelineBarrier(vk,
native, PipelineStageFlags.AllCommandsBit, PipelineStageFlags.TransferBit, DependencyFlags.ByRegionBit,
0, null, 1, &before, 0, null);
var regions = CollectionsMarshal.AsSpan(copies);
@ -1035,9 +1036,9 @@ public sealed unsafe class GuestBufferCache : IGuestBufferStore, IDisposable
}
var after = before;
after.SrcAccessMask = AccessFlags.TransferWriteBit;
after.DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit;
vk.CmdPipelineBarrier(
after.SrcAccessMask = AccessFlags2.TransferWriteBit;
after.DstAccessMask = AccessFlags2.MemoryReadBit | AccessFlags2.MemoryWriteBit;
VulkanSynchronization.PipelineBarrier(vk,
native, PipelineStageFlags.TransferBit, PipelineStageFlags.AllCommandsBit, DependencyFlags.ByRegionBit,
0, null, 1, &after, 0, null);
}