[GPU] Request guest memory barriers through the recording buffer

This commit is contained in:
ParantezTech 2026-10-11 01:36:17 +03:00
parent c622b64ace
commit 6d69163297
5 changed files with 54 additions and 7 deletions

View File

@ -1048,6 +1048,8 @@ internal static unsafe partial class VulkanVideoPresenter
continue;
}
_commandBuffer = BeginBatchedGuestCommands();
var initialized = texture.HostMoviePlane == 0 ? _hostMovieImageInitialized : _hostMovieChromaImageInitialized;
var toTransfer = new ImageMemoryBarrier2
{

View File

@ -541,6 +541,12 @@ internal static unsafe partial class VulkanVideoPresenter
}
EndRendering();
if (BatchBarriers)
{
RequestGuestMemoryBarrier(GlobalMemoryBarrier);
return;
}
RecordGlobalBarrier(BeginBatchedGuestCommands());
}

View File

@ -842,7 +842,7 @@ internal static unsafe partial class VulkanVideoPresenter
using var profileScope = RenderPhaseProfile.MeasureDetail(RenderPhaseProfile.Phase.DescriptorCommit);
var preparation = RequirePreparation();
var entry = RequirePipelineEntry(in pipeline);
var command = BeginBatchedGuestCommands();
var command = BeginBatchedGuestStateCommands();
_commandBuffer = command;
var writeCount = 0;
var bufferCount = 0;

View File

@ -47,13 +47,32 @@ internal static unsafe partial class VulkanVideoPresenter
private CommandBuffer BeginBatchedGuestCommands()
{
var commandBuffer = CurrentRecordingBuffer();
OpenGuestBatch();
return commandBuffer;
}
private CommandBuffer BeginBatchedGuestStateCommands()
{
var recording = CurrentRecording();
OpenGuestBatch();
return new CommandBuffer(recording.StateHandle);
}
private void RequestGuestMemoryBarrier(in MemoryBarrierRequest request)
{
var recording = CurrentRecording();
OpenGuestBatch();
_scheduler.MemoryBarrierRecorder ??= RecordRequestedMemoryBarrier;
recording.RequestMemoryBarrier(request);
}
private void OpenGuestBatch()
{
if (!_batchOpen)
{
_batchOpen = true;
_batchDrawCount = 0;
}
return commandBuffer;
}
// Submits the current recording buffer with everything the batch lists own.

View File

@ -856,12 +856,17 @@ internal static unsafe partial class VulkanVideoPresenter
}
EndRendering();
var command = BeginBatchedGuestCommands();
_commandBuffer = command;
if (DeferGlobalBarriers)
if (DeferGlobalBarriers && BatchBarriers)
{
// A guest cache flush inside this scope may be deferred to its end; this keeps
// everything recorded before the scope ordered before its draws either way.
RequestGuestMemoryBarrier(GlobalMemoryBarrier);
}
var command = BeginBatchedGuestCommands();
_commandBuffer = command;
if (DeferGlobalBarriers && !BatchBarriers)
{
RecordGlobalBarrier(command);
}
@ -986,7 +991,7 @@ internal static unsafe partial class VulkanVideoPresenter
public void BindPipeline(PipelineBindPoint bindPoint, in PipelineHandle pipeline)
{
var entry = RequirePipelineEntry(in pipeline);
var command = BeginBatchedGuestCommands();
var command = BeginBatchedGuestStateCommands();
if (bindPoint == PipelineBindPoint.Graphics)
{
_boundGraphicsPipeline = entry;
@ -1149,9 +1154,24 @@ internal static unsafe partial class VulkanVideoPresenter
return true;
}
private static readonly bool BatchBarriers =
Environment.GetEnvironmentVariable("SHARPEMU_BATCH_BARRIERS") != "0";
private static readonly MemoryBarrierRequest GlobalMemoryBarrier = new(
PipelineStageFlags.AllCommandsBit,
PipelineStageFlags.AllCommandsBit,
AccessFlags.MemoryWriteBit,
AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit);
private void RecordMemoryBarrier(PipelineStageFlags sourceStages, PipelineStageFlags destinationStages, AccessFlags sourceAccess, AccessFlags destinationAccess)
{
EndRendering();
if (BatchBarriers)
{
RequestGuestMemoryBarrier(new MemoryBarrierRequest(sourceStages, destinationStages, sourceAccess, destinationAccess));
return;
}
var command = BeginBatchedGuestCommands();
var barrier = new MemoryBarrier2
{