Skip to content

Commit

Permalink
Only use persistent buffers to flush on NVIDIA and Windows+AMD (#2489)
Browse files Browse the repository at this point in the history
It seems like this method of flushing data is much slower on Mesa drivers, and slightly slower on Intel Windows. Have not tested Intel Mesa, but I'm assuming it is the same as AMD.

This also adds vendor detection for AMD on Unix, which counted as "Unknown" before.
  • Loading branch information
riperiperi authored Jul 18, 2021
1 parent b8ad676 commit 10e17ab
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
18 changes: 14 additions & 4 deletions Ryujinx.Graphics.OpenGL/HwCapabilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,24 @@ static class HwCapabilities
public enum GpuVendor
{
Unknown,
Amd,
AmdWindows,
AmdUnix,
IntelWindows,
IntelUnix,
Nvidia
}

private static readonly Lazy<GpuVendor> _gpuVendor = new Lazy<GpuVendor>(GetGpuVendor);

private static bool _isAMD => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.AmdUnix;
private static bool _isIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;

public static GpuVendor Vendor => _gpuVendor.Value;

private static Lazy<float> _maxSupportedAnisotropy = new Lazy<float>(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));

public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;

public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
Expand All @@ -41,9 +47,9 @@ public enum GpuVendor
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;

public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.Amd && _gpuVendor.Value != GpuVendor.IntelWindows;
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.Amd || _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _isIntel;

public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
Expand Down Expand Up @@ -86,7 +92,11 @@ private static GpuVendor GetGpuVendor()
}
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
{
return GpuVendor.Amd;
return GpuVendor.AmdWindows;
}
else if (vendor == "amd" || vendor == "x.org")
{
return GpuVendor.AmdUnix;
}
else
{
Expand Down
26 changes: 25 additions & 1 deletion Ryujinx.Graphics.OpenGL/Image/TextureView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,31 @@ public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegio

public byte[] GetData()
{
return _renderer.PersistentBuffers.Default.GetTextureData(this);
int size = 0;

for (int level = 0; level < Info.Levels; level++)
{
size += Info.GetMipSize(level);
}

if (HwCapabilities.UsePersistentBufferForFlush)
{
return _renderer.PersistentBuffers.Default.GetTextureData(this, size);
}
else
{
byte[] data = new byte[size];

unsafe
{
fixed (byte* ptr = data)
{
WriteTo((IntPtr)ptr);
}
}

return data;
}
}

public void WriteToPbo(int offset, bool forceBgra)
Expand Down
9 changes: 1 addition & 8 deletions Ryujinx.Graphics.OpenGL/PersistentBuffers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,8 @@ private void Sync()
GL.DeleteSync(sync);
}

public byte[] GetTextureData(TextureView view)
public byte[] GetTextureData(TextureView view, int size)
{
int size = 0;

for (int level = 0; level < view.Info.Levels; level++)
{
size += view.Info.GetMipSize(level);
}

EnsureBuffer(size);

GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyBufferHandle);
Expand Down
9 changes: 8 additions & 1 deletion Ryujinx.Graphics.OpenGL/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,14 @@ public void DeleteBuffer(BufferHandle buffer)

public byte[] GetBufferData(BufferHandle buffer, int offset, int size)
{
return PersistentBuffers.Default.GetBufferData(buffer, offset, size);
if (HwCapabilities.UsePersistentBufferForFlush)
{
return PersistentBuffers.Default.GetBufferData(buffer, offset, size);
}
else
{
return Buffer.GetData(buffer, offset, size);
}
}

public Capabilities GetCapabilities()
Expand Down

0 comments on commit 10e17ab

Please sign in to comment.