mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
Report 32 bit query result on AMD windows (smo issue)
This commit is contained in:
parent
7838a45772
commit
646be812ed
3 changed files with 28 additions and 12 deletions
|
@ -11,6 +11,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
private const int MaxQueryRetries = 5000;
|
private const int MaxQueryRetries = 5000;
|
||||||
private const long DefaultValue = -1;
|
private const long DefaultValue = -1;
|
||||||
|
private const long DefaultValueInt = 0xFFFFFFFF;
|
||||||
|
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
|
@ -22,13 +23,17 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
private readonly BufferHolder _buffer;
|
private readonly BufferHolder _buffer;
|
||||||
private readonly IntPtr _bufferMap;
|
private readonly IntPtr _bufferMap;
|
||||||
private readonly CounterType _type;
|
private readonly CounterType _type;
|
||||||
|
private bool _result32Bit;
|
||||||
|
|
||||||
public unsafe BufferedQuery(VulkanGraphicsDevice gd, Device device, PipelineFull pipeline, CounterType type)
|
private long _defaultValue;
|
||||||
|
|
||||||
|
public unsafe BufferedQuery(VulkanGraphicsDevice gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
||||||
{
|
{
|
||||||
_api = gd.Api;
|
_api = gd.Api;
|
||||||
_device = device;
|
_device = device;
|
||||||
_pipeline = pipeline;
|
_pipeline = pipeline;
|
||||||
_type = type;
|
_type = type;
|
||||||
|
_result32Bit = result32Bit;
|
||||||
|
|
||||||
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
|
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
|
||||||
QueryPipelineStatisticFlags.QueryPipelineStatisticGeometryShaderPrimitivesBit : 0;
|
QueryPipelineStatisticFlags.QueryPipelineStatisticGeometryShaderPrimitivesBit : 0;
|
||||||
|
@ -46,7 +51,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
var buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true);
|
var buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true);
|
||||||
|
|
||||||
_bufferMap = buffer.Map(0, sizeof(long));
|
_bufferMap = buffer.Map(0, sizeof(long));
|
||||||
Marshal.WriteInt64(_bufferMap, DefaultValue);
|
_defaultValue = result32Bit ? DefaultValueInt : DefaultValue;
|
||||||
|
Marshal.WriteInt64(_bufferMap, _defaultValue);
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|
||||||
if (withResult)
|
if (withResult)
|
||||||
{
|
{
|
||||||
Marshal.WriteInt64(_bufferMap, DefaultValue);
|
Marshal.WriteInt64(_bufferMap, _defaultValue);
|
||||||
_pipeline.CopyQueryResults(this);
|
_pipeline.CopyQueryResults(this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -98,16 +104,16 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
result = Marshal.ReadInt64(_bufferMap);
|
result = Marshal.ReadInt64(_bufferMap);
|
||||||
|
|
||||||
return result != DefaultValue;
|
return result != _defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AwaitResult(AutoResetEvent wakeSignal = null)
|
public long AwaitResult(AutoResetEvent wakeSignal = null)
|
||||||
{
|
{
|
||||||
long data = DefaultValue;
|
long data = _defaultValue;
|
||||||
|
|
||||||
if (wakeSignal == null)
|
if (wakeSignal == null)
|
||||||
{
|
{
|
||||||
while (data == DefaultValue)
|
while (data == _defaultValue)
|
||||||
{
|
{
|
||||||
data = Marshal.ReadInt64(_bufferMap);
|
data = Marshal.ReadInt64(_bufferMap);
|
||||||
}
|
}
|
||||||
|
@ -115,10 +121,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
while (data == DefaultValue && iterations++ < MaxQueryRetries)
|
while (data == _defaultValue && iterations++ < MaxQueryRetries)
|
||||||
{
|
{
|
||||||
data = Marshal.ReadInt64(_bufferMap);
|
data = Marshal.ReadInt64(_bufferMap);
|
||||||
if (data == DefaultValue)
|
if (data == _defaultValue)
|
||||||
{
|
{
|
||||||
wakeSignal.WaitOne(1);
|
wakeSignal.WaitOne(1);
|
||||||
}
|
}
|
||||||
|
@ -143,6 +149,13 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
var buffer = _buffer.GetBuffer(cbs.CommandBuffer, true).Get(cbs, 0, sizeof(long)).Value;
|
var buffer = _buffer.GetBuffer(cbs.CommandBuffer, true).Get(cbs, 0, sizeof(long)).Value;
|
||||||
|
|
||||||
|
QueryResultFlags flags = QueryResultFlags.QueryResultWaitBit;
|
||||||
|
|
||||||
|
if (!_result32Bit)
|
||||||
|
{
|
||||||
|
flags |= QueryResultFlags.QueryResult64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
_api.CmdCopyQueryPoolResults(
|
_api.CmdCopyQueryPoolResults(
|
||||||
cbs.CommandBuffer,
|
cbs.CommandBuffer,
|
||||||
_queryPool,
|
_queryPool,
|
||||||
|
@ -150,8 +163,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
1,
|
1,
|
||||||
buffer,
|
buffer,
|
||||||
0,
|
0,
|
||||||
sizeof(long),
|
(ulong)(_result32Bit ? sizeof(int) : sizeof(long)),
|
||||||
QueryResultFlags.QueryResult64Bit | QueryResultFlags.QueryResultWaitBit);
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Dispose()
|
public unsafe void Dispose()
|
||||||
|
|
|
@ -43,7 +43,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);
|
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);
|
||||||
for (int i = 0; i < QueryPoolInitialSize; i++)
|
for (int i = 0; i < QueryPoolInitialSize; i++)
|
||||||
{
|
{
|
||||||
_queryPool.Enqueue(new BufferedQuery(_gd, _device, _pipeline, type));
|
// AMD Polaris GPUs on Windows seem to have issues reporting 64-bit query results.
|
||||||
|
_queryPool.Enqueue(new BufferedQuery(_gd, _device, _pipeline, type, gd.IsAmdWindows));
|
||||||
}
|
}
|
||||||
|
|
||||||
_current = new CounterQueueEvent(this, type, 0);
|
_current = new CounterQueueEvent(this, type, 0);
|
||||||
|
@ -96,7 +97,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new BufferedQuery(_gd, _device, _pipeline, Type);
|
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private Func<string[]> GetRequiredExtensions;
|
private Func<string[]> GetRequiredExtensions;
|
||||||
|
|
||||||
internal Vendor Vendor { get; private set; }
|
internal Vendor Vendor { get; private set; }
|
||||||
|
internal bool IsAmdWindows { get; private set; }
|
||||||
internal bool IsIntelWindows { get; private set; }
|
internal bool IsIntelWindows { get; private set; }
|
||||||
public string GpuVendor { get; private set; }
|
public string GpuVendor { get; private set; }
|
||||||
public string GpuRenderer { get; private set; }
|
public string GpuRenderer { get; private set; }
|
||||||
|
@ -385,6 +386,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_ => Vendor.Unknown
|
_ => Vendor.Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
|
IsAmdWindows = Vendor == Vendor.Amd && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
IsIntelWindows = Vendor == Vendor.Intel && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
IsIntelWindows = Vendor == Vendor.Intel && RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||||
|
|
||||||
GpuVendor = vendorName;
|
GpuVendor = vendorName;
|
||||||
|
|
Loading…
Reference in a new issue