aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2023-03-12 17:01:15 +0000
committerGitHub <noreply@github.com>2023-03-12 18:01:15 +0100
commit6e9bd4de138e6ddedef3d38d711d161a0e400d5c (patch)
treed8df41e79eae9ae9fe333f95fc15c2f43e4e0584 /Ryujinx.Graphics.Vulkan
parent05a41b31bc4d2b973662ac370458697c0bf712a9 (diff)
GPU: Scale counter results before addition (#4471)1.1.662
* GPU: Scale counter results before addition Counter results were being scaled on ReportCounter, which meant that the _total_ value of the counter was being scaled. Not only could this result in very large numbers and weird overflows if the game doesn't clear the counter, but it also caused the result to change drastically. This PR changes scaling to be done when the value is added to the counter on the backend. This should evaluate the scale at the same time as before, on report counter, but avoiding the issue with scaling the total. Fixes scaling in Warioware, at least in the demo, where it seems to compare old/new counters and broke down when scaling was enabled. * Fix issues when result is partially uploaded. Drivers tend to write the low half first, then the high half. Retry if the high half is FFFFFFFF.
Diffstat (limited to 'Ryujinx.Graphics.Vulkan')
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineBase.cs10
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs13
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs2
-rw-r--r--Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs7
4 files changed, 26 insertions, 6 deletions
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 583bb953..3abab065 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -684,6 +684,16 @@ namespace Ryujinx.Graphics.Vulkan
_tfEnabled = false;
}
+ public double GetCounterDivisor(CounterType type)
+ {
+ if (type == CounterType.SamplesPassed)
+ {
+ return _renderScale[0].X * _renderScale[0].X;
+ }
+
+ return 1;
+ }
+
public bool IsCommandBufferActive(CommandBuffer cb)
{
return CommandBuffer.Handle == cb.Handle;
diff --git a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
index 29efd8e7..861155a3 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/BufferedQuery.cs
@@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private const int MaxQueryRetries = 5000;
private const long DefaultValue = -1;
private const long DefaultValueInt = 0xFFFFFFFF;
+ private const ulong HighMask = 0xFFFFFFFF00000000;
private readonly Vk _api;
private readonly Device _device;
@@ -125,6 +126,12 @@ namespace Ryujinx.Graphics.Vulkan.Queries
}
}
+ private bool WaitingForValue(long data)
+ {
+ return data == _defaultValue ||
+ (!_result32Bit && ((ulong)data & HighMask) == ((ulong)_defaultValue & HighMask));
+ }
+
public bool TryGetResult(out long result)
{
result = Marshal.ReadInt64(_bufferMap);
@@ -138,7 +145,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
if (wakeSignal == null)
{
- while (data == _defaultValue)
+ while (WaitingForValue(data))
{
data = Marshal.ReadInt64(_bufferMap);
}
@@ -146,10 +153,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
else
{
int iterations = 0;
- while (data == _defaultValue && iterations++ < MaxQueryRetries)
+ while (WaitingForValue(data) && iterations++ < MaxQueryRetries)
{
data = Marshal.ReadInt64(_bufferMap);
- if (data == _defaultValue)
+ if (WaitingForValue(data))
{
wakeSignal.WaitOne(1);
}
diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
index 7293b74f..c30d91c4 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs
@@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
_current.ReserveForHostAccess();
}
- _current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten);
+ _current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten, _pipeline.GetCounterDivisor(Type));
_events.Enqueue(_current);
_current.OnResult += resultHandler;
diff --git a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
index 6b780ba3..d3aedb2f 100644
--- a/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
+++ b/Ryujinx.Graphics.Vulkan/Queries/CounterQueueEvent.cs
@@ -24,6 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private object _lock = new object();
private ulong _result = ulong.MaxValue;
+ private double _divisor = 1f;
public CounterQueueEvent(CounterQueue queue, CounterType type, ulong drawIndex)
{
@@ -52,9 +53,11 @@ namespace Ryujinx.Graphics.Vulkan.Queries
ClearCounter = true;
}
- internal void Complete(bool withResult)
+ internal void Complete(bool withResult, double divisor)
{
_counter.End(withResult);
+
+ _divisor = divisor;
}
internal bool TryConsume(ref ulong result, bool block, AutoResetEvent wakeSignal = null)
@@ -85,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
}
}
- result += (ulong)queryResult;
+ result += _divisor == 1 ? (ulong)queryResult : (ulong)Math.Ceiling(queryResult / _divisor);
_result = result;