[Presenter] Merge overlapping concurrent resolve ownership answers

This commit is contained in:
ParantezTech 2026-10-11 06:11:55 +03:00
parent 002007c323
commit 6631a665f8
1 changed files with 40 additions and 22 deletions

View File

@ -8,6 +8,46 @@ using SharpEmu.Libs.Gpu.Scheduling;
internal static unsafe partial class VulkanVideoPresenter
{
internal enum ConcurrentQuery : byte
{
DirtyBytes,
CleanWord,
Resident,
ResidentClean,
}
internal sealed class ConcurrentAssumptions(long bufferVersion, long writebackEpoch)
{
public readonly long BufferVersion = bufferVersion;
public readonly long WritebackEpoch = writebackEpoch;
public readonly List<(ConcurrentQuery Query, ulong Address, ulong Size, bool Answer)> Answers = new();
public bool ReadsImageOwnership;
public void Record(ConcurrentQuery query, ulong address, ulong size, bool answer)
{
ReadsImageOwnership |= query is ConcurrentQuery.CleanWord or ConcurrentQuery.ResidentClean;
for (var index = Answers.Count - 1; index >= Math.Max(0, Answers.Count - 8); index--)
{
var previous = Answers[index];
if (previous.Query != query || previous.Answer != answer)
continue;
if (previous.Address == address && previous.Size == size)
return;
// No owned bytes in either range proves the union, but an owned byte does not.
if (!answer && size <= ulong.MaxValue - address && previous.Size <= ulong.MaxValue - previous.Address &&
address <= previous.Address + previous.Size && previous.Address <= address + size)
{
var start = Math.Min(address, previous.Address);
var end = Math.Max(address + size, previous.Address + previous.Size);
Answers[index] = (query, start, end - start, false);
return;
}
}
Answers.Add((query, address, size, answer));
}
}
private sealed partial class Presenter : IConcurrentResolveHost
{
// This partial serves the guest readers of program resolution on a thread resolving draws
@ -15,28 +55,6 @@ internal static unsafe partial class VulkanVideoPresenter
// GPU owns abandons the resolution, which the render thread then does itself. Every
// ownership answer it relied on is recorded and checked again when the result is taken.
private enum ConcurrentQuery : byte
{
DirtyBytes,
CleanWord,
Resident,
ResidentClean,
}
private sealed class ConcurrentAssumptions(long bufferVersion, long writebackEpoch)
{
public readonly long BufferVersion = bufferVersion;
public readonly long WritebackEpoch = writebackEpoch;
public readonly List<(ConcurrentQuery Query, ulong Address, ulong Size, bool Answer)> Answers = new();
public bool ReadsImageOwnership;
public void Record(ConcurrentQuery query, ulong address, ulong size, bool answer)
{
Answers.Add((query, address, size, answer));
ReadsImageOwnership |= query is ConcurrentQuery.CleanWord or ConcurrentQuery.ResidentClean;
}
}
// Set only on the resolving thread, around one resolution.
[ThreadStatic]
private static ConcurrentAssumptions? _concurrentAssumptions;