Compare commits

...

2 Commits

Author SHA1 Message Date
TSRBerry
40f2bd37e3 [Ryujinx.Graphics.OpenGL] Address dotnet-format issues (#5372)
* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Address or silence dotnet format IDE1006 warnings

* Fix IDE0090 after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Start working on disabled warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Address review feedback
2023-06-28 18:10:55 +02:00
Ac_K
9288ffd26d Cpu: Implement VCVT (between floating-point and fixed-point) instruction (#5343)
* cpu: Implement VCVT (between floating-point and fixed-point) instruction

Rebase, fix and superseed of https://github.com/Ryujinx/Ryujinx/pull/2915

(Since I only have little CPU knowledge, I hope I have done everything good)

* Update Ptc.cs

* Fix wrong cast

* Rename tests

* Addresses feedback

Co-Authored-By: gdkchan <5624669+gdkchan@users.noreply.github.com>

* Remove extra empty line

---------

Co-authored-by: gdkchan <5624669+gdkchan@users.noreply.github.com>
2023-06-28 17:36:30 +02:00
38 changed files with 507 additions and 373 deletions

View File

@@ -0,0 +1,23 @@
namespace ARMeilleure.Decoders
{
class OpCode32SimdCvtFFixed : OpCode32Simd
{
public int Fbits { get; protected set; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, false);
public new static OpCode CreateT32(InstDescriptor inst, ulong address, int opCode) => new OpCode32SimdCvtFFixed(inst, address, opCode, true);
public OpCode32SimdCvtFFixed(InstDescriptor inst, ulong address, int opCode, bool isThumb) : base(inst, address, opCode, isThumb)
{
Opc = (opCode >> 8) & 0x1;
Size = Opc == 1 ? 0 : 2;
Fbits = 64 - ((opCode >> 16) & 0x3f);
if (DecoderHelper.VectorArgumentsInvalid(Q, Vd, Vm))
{
Instruction = InstDescriptor.Undefined;
}
}
}
}

View File

@@ -918,6 +918,7 @@ namespace ARMeilleure.Decoders
SetAsimd("111100111x11xx01xxxx0x100xx0xxxx", InstName.Vclt, InstEmit32.Vclt_Z, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32);
SetAsimd("111100111x110000xxxx01010xx0xxxx", InstName.Vcnt, InstEmit32.Vcnt, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32);
SetAsimd("111100111x111011xxxx011xxxx0xxxx", InstName.Vcvt, InstEmit32.Vcvt_V, OpCode32SimdCmpZ.Create, OpCode32SimdCmpZ.CreateT32); // FP and integer, vector.
SetAsimd("1111001x1x1xxxxxxxxx111x0xx1xxxx", InstName.Vcvt, InstEmit32.Vcvt_V_Fixed, OpCode32SimdCvtFFixed.Create, OpCode32SimdCvtFFixed.CreateT32); // Between floating point and fixed point, vector.
SetAsimd("111100111x11xxxxxxxx11000xx0xxxx", InstName.Vdup, InstEmit32.Vdup_1, OpCode32SimdDupElem.Create, OpCode32SimdDupElem.CreateT32);
SetAsimd("111100110x00xxxxxxxx0001xxx1xxxx", InstName.Veor, InstEmit32.Veor_I, OpCode32SimdBinary.Create, OpCode32SimdBinary.CreateT32);
SetAsimd("111100101x11xxxxxxxxxxxxxxx0xxxx", InstName.Vext, InstEmit32.Vext, OpCode32SimdExt.Create, OpCode32SimdExt.CreateT32);

View File

@@ -114,6 +114,35 @@ namespace ARMeilleure.Instructions
}
}
public static void Vcvt_V_Fixed(ArmEmitterContext context)
{
OpCode32SimdCvtFFixed op = (OpCode32SimdCvtFFixed)context.CurrOp;
var toFixed = op.Opc == 1;
int fracBits = op.Fbits;
var unsigned = op.U;
if (toFixed) // F32 to S32 or U32 (fixed)
{
EmitVectorUnaryOpF32(context, (op1) =>
{
var scaledValue = context.Multiply(op1, ConstF(MathF.Pow(2f, fracBits)));
MethodInfo info = unsigned ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32)) : typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32));
return context.Call(info, scaledValue);
});
}
else // S32 or U32 (fixed) to F32
{
EmitVectorUnaryOpI32(context, (op1) =>
{
var floatValue = unsigned ? context.ConvertToFPUI(OperandType.FP32, op1) : context.ConvertToFP(OperandType.FP32, op1);
return context.Multiply(floatValue, ConstF(1f / MathF.Pow(2f, fracBits)));
}, !unsigned);
}
}
public static void Vcvt_FD(ArmEmitterContext context)
{
OpCode32SimdS op = (OpCode32SimdS)context.CurrOp;

View File

@@ -29,7 +29,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 5292; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 5343; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";

View File

@@ -9,12 +9,12 @@ namespace Ryujinx.Graphics.OpenGL
{
[ThreadStatic]
public static bool InBackground;
private Thread _thread;
private readonly Thread _thread;
private bool _running;
private AutoResetEvent _signal;
private Queue<Action> _work;
private ObjectPool<ManualResetEventSlim> _invokePool;
private readonly AutoResetEvent _signal;
private readonly Queue<Action> _work;
private readonly ObjectPool<ManualResetEventSlim> _invokePool;
private readonly IOpenGLContext _backgroundContext;
public BackgroundContextWorker(IOpenGLContext backgroundContext)

View File

@@ -63,10 +63,18 @@ namespace Ryujinx.Graphics.OpenGL
switch (type)
{
case DebugType.DebugTypeError : Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR"); break;
case DebugType.DebugTypePerformance: Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF"); break;
case DebugType.DebugTypePushGroup : Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO"); break;
case DebugType.DebugTypePopGroup : Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO"); break;
case DebugType.DebugTypeError:
Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR");
break;
case DebugType.DebugTypePerformance:
Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF");
break;
case DebugType.DebugTypePushGroup:
Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO");
break;
case DebugType.DebugTypePopGroup:
Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO");
break;
default:
if (source == DebugSource.DebugSourceApplication)
{

View File

@@ -65,16 +65,12 @@ void main()
if (x0 > x1)
{
float temp = s0;
s0 = s1;
s1 = temp;
(s1, s0) = (s0, s1);
}
if (y0 > y1)
{
float temp = t0;
t0 = t1;
t1 = temp;
(t1, t0) = (t0, t1);
}
GL.Uniform1(_uniformSrcX0Location, s0);

View File

@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
}
}
public FsrScalingFilter(OpenGLRenderer renderer, IPostProcessingEffect filter)
public FsrScalingFilter(OpenGLRenderer renderer)
{
Initialize();

View File

@@ -1,5 +1,4 @@
using OpenTK.Graphics.OpenGL;
using System;
namespace Ryujinx.Graphics.OpenGL.Effects
{

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
private int[] _neighbourShaderPrograms;
private TextureStorage _edgeOutputTexture;
private TextureStorage _blendOutputTexture;
private string[] _qualities;
private readonly string[] _qualities;
private int _inputUniform;
private int _outputUniform;
private int _samplerAreaUniform;

View File

@@ -4,10 +4,10 @@ using System;
namespace Ryujinx.Graphics.OpenGL
{
struct FormatTable
readonly struct FormatTable
{
private static FormatInfo[] _table;
private static SizedInternalFormat[] _tableImage;
private static readonly FormatInfo[] _table;
private static readonly SizedInternalFormat[] _tableImage;
static FormatTable()
{
@@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.OpenGL
_table = new FormatInfo[tableSize];
_tableImage = new SizedInternalFormat[tableSize];
#pragma warning disable IDE0055 // Disable formatting
Add(Format.R8Unorm, new FormatInfo(1, true, false, All.R8, PixelFormat.Red, PixelType.UnsignedByte));
Add(Format.R8Snorm, new FormatInfo(1, true, false, All.R8Snorm, PixelFormat.Red, PixelType.Byte));
Add(Format.R8Uint, new FormatInfo(1, false, false, All.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
@@ -200,6 +201,7 @@ namespace Ryujinx.Graphics.OpenGL
Add(Format.R10G10B10A2Unorm, (SizedInternalFormat)All.Rgb10A2);
Add(Format.R10G10B10A2Uint, (SizedInternalFormat)All.Rgb10A2ui);
Add(Format.R11G11B10Float, (SizedInternalFormat)All.R11fG11fB10f);
#pragma warning restore IDE0055
}
private static void Add(Format format, FormatInfo info)

View File

@@ -105,7 +105,7 @@ namespace Ryujinx.Graphics.OpenGL
_colorsCount = colorsCount;
}
private void SetDrawBuffersImpl(int colorsCount)
private static void SetDrawBuffersImpl(int colorsCount)
{
DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount];

View File

@@ -5,30 +5,30 @@ namespace Ryujinx.Graphics.OpenGL
{
static class HwCapabilities
{
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new Lazy<bool>(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
private static readonly Lazy<bool> _supportsAstcCompression = new Lazy<bool>(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new Lazy<bool>(() => HasExtension("GL_NV_blend_equation_advanced"));
private static readonly Lazy<bool> _supportsDrawTexture = new Lazy<bool>(() => HasExtension("GL_NV_draw_texture"));
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new Lazy<bool>(() => HasExtension("GL_ARB_fragment_shader_interlock"));
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new Lazy<bool>(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new Lazy<bool>(() => HasExtension("GL_NV_geometry_shader_passthrough"));
private static readonly Lazy<bool> _supportsImageLoadFormatted = new Lazy<bool>(() => HasExtension("GL_EXT_shader_image_load_formatted"));
private static readonly Lazy<bool> _supportsIndirectParameters = new Lazy<bool>(() => HasExtension("GL_ARB_indirect_parameters"));
private static readonly Lazy<bool> _supportsParallelShaderCompile = new Lazy<bool>(() => HasExtension("GL_ARB_parallel_shader_compile"));
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new Lazy<bool>(() => HasExtension("GL_EXT_polygon_offset_clamp"));
private static readonly Lazy<bool> _supportsQuads = new Lazy<bool>(SupportsQuadsCheck);
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new Lazy<bool>(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsShaderBallot = new Lazy<bool>(() => HasExtension("GL_ARB_shader_ballot"));
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new Lazy<bool>(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
private static readonly Lazy<bool> _supportsViewportArray2 = new Lazy<bool>(() => HasExtension("GL_NV_viewport_array2"));
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_bptc"));
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_rgtc"));
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new Lazy<bool>(() => HasExtension("GL_EXT_texture_compression_s3tc"));
private static readonly Lazy<bool> _supportsTextureShadowLod = new Lazy<bool>(() => HasExtension("GL_EXT_texture_shadow_lod"));
private static readonly Lazy<bool> _supportsViewportSwizzle = new Lazy<bool>(() => HasExtension("GL_NV_viewport_swizzle"));
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
private static readonly Lazy<bool> _supportsAstcCompression = new(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new(() => HasExtension("GL_NV_blend_equation_advanced"));
private static readonly Lazy<bool> _supportsDrawTexture = new(() => HasExtension("GL_NV_draw_texture"));
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new(() => HasExtension("GL_ARB_fragment_shader_interlock"));
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new(() => HasExtension("GL_NV_geometry_shader_passthrough"));
private static readonly Lazy<bool> _supportsImageLoadFormatted = new(() => HasExtension("GL_EXT_shader_image_load_formatted"));
private static readonly Lazy<bool> _supportsIndirectParameters = new(() => HasExtension("GL_ARB_indirect_parameters"));
private static readonly Lazy<bool> _supportsParallelShaderCompile = new(() => HasExtension("GL_ARB_parallel_shader_compile"));
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new(() => HasExtension("GL_EXT_polygon_offset_clamp"));
private static readonly Lazy<bool> _supportsQuads = new(SupportsQuadsCheck);
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
private static readonly Lazy<bool> _supportsShaderBallot = new(() => HasExtension("GL_ARB_shader_ballot"));
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
private static readonly Lazy<bool> _supportsViewportArray2 = new(() => HasExtension("GL_NV_viewport_array2"));
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new(() => HasExtension("GL_EXT_texture_compression_bptc"));
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new(() => HasExtension("GL_EXT_texture_compression_rgtc"));
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new(() => HasExtension("GL_EXT_texture_compression_s3tc"));
private static readonly Lazy<bool> _supportsTextureShadowLod = new(() => HasExtension("GL_EXT_texture_shadow_lod"));
private static readonly Lazy<bool> _supportsViewportSwizzle = new(() => HasExtension("GL_NV_viewport_swizzle"));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new Lazy<int>(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new Lazy<int>(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new(() => GetLimit(All.MaxComputeSharedMemorySize));
private static readonly Lazy<int> _storageBufferOffsetAlignment = new(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
public enum GpuVendor
{
@@ -40,14 +40,13 @@ namespace Ryujinx.Graphics.OpenGL
Nvidia
}
private static readonly Lazy<GpuVendor> _gpuVendor = new Lazy<GpuVendor>(GetGpuVendor);
private static readonly Lazy<GpuVendor> _gpuVendor = new(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;
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));
private static readonly Lazy<float> _maxSupportedAnisotropy = new(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));
public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;
@@ -75,7 +74,7 @@ namespace Ryujinx.Graphics.OpenGL
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.AmdWindows || _isIntel;
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || IsIntel;
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;

View File

@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
class TextureBuffer : TextureBase, ITexture
{
private OpenGLRenderer _renderer;
private readonly OpenGLRenderer _renderer;
private int _bufferOffset;
private int _bufferSize;
private int _bufferCount;
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
var dataSpan = data.AsSpan();
Buffer.SetData(_buffer, _bufferOffset, dataSpan.Slice(0, Math.Min(dataSpan.Length, _bufferSize)));
Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
}
public void SetData(SpanOrArray<byte> data, int layer, int level)

View File

@@ -1,5 +1,4 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -81,9 +80,6 @@ void main()
public void CopyIncompatibleFormats(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int depth, int levels)
{
TextureCreateInfo srcInfo = src.Info;
TextureCreateInfo dstInfo = dst.Info;
int srcBpp = src.Info.BytesPerPixel;
int dstBpp = dst.Info.BytesPerPixel;
@@ -176,7 +172,7 @@ void main()
return GetShader(ComputeShaderWidening, _wideningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount);
}
private int GetShader(
private static int GetShader(
string code,
Dictionary<int, int> programHandles,
int componentSize,

View File

@@ -94,8 +94,8 @@ void main()
}";
private readonly OpenGLRenderer _renderer;
private int[] _msToNonMSProgramHandles;
private int[] _nonMSToMSProgramHandles;
private readonly int[] _msToNonMSProgramHandles;
private readonly int[] _nonMSToMSProgramHandles;
public TextureCopyMS(OpenGLRenderer renderer)
{
@@ -219,7 +219,7 @@ void main()
return GetShader(ComputeShaderNonMSToMS, _nonMSToMSProgramHandles, bytesPerPixel);
}
private int GetShader(string code, int[] programHandles, int bytesPerPixel)
private static int GetShader(string code, int[] programHandles, int bytesPerPixel)
{
int index = BitOperations.Log2((uint)bytesPerPixel);

View File

@@ -88,9 +88,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
// Swap B <-> R for BGRA formats, as OpenGL has no support for them
// and we need to manually swap the components on read/write on the GPU.
int temp = swizzleRgba[0];
swizzleRgba[0] = swizzleRgba[2];
swizzleRgba[2] = temp;
(swizzleRgba[2], swizzleRgba[0]) = (swizzleRgba[0], swizzleRgba[2]);
}
GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba);
@@ -186,8 +184,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
// This approach uses blit, which causes a resolution loss since some samples will be lost
// in the process.
Extents2D srcRegion = new Extents2D(0, 0, Width, Height);
Extents2D dstRegion = new Extents2D(0, 0, destinationView.Width, destinationView.Height);
Extents2D srcRegion = new(0, 0, Width, Height);
Extents2D dstRegion = new(0, 0, destinationView.Width, destinationView.Height);
if (destinationView.Target.IsMultisample())
{

View File

@@ -21,13 +21,13 @@ namespace Ryujinx.Graphics.OpenGL
public IWindow Window => _window;
private TextureCopy _textureCopy;
private TextureCopy _backgroundTextureCopy;
private readonly TextureCopy _textureCopy;
private readonly TextureCopy _backgroundTextureCopy;
internal TextureCopy TextureCopy => BackgroundContextWorker.InBackground ? _backgroundTextureCopy : _textureCopy;
internal TextureCopyIncompatible TextureCopyIncompatible { get; }
internal TextureCopyMS TextureCopyMS { get; }
private Sync _sync;
private readonly Sync _sync;
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;

View File

@@ -11,10 +11,10 @@ namespace Ryujinx.Graphics.OpenGL
{
class PersistentBuffers : IDisposable
{
private PersistentBuffer _main = new PersistentBuffer();
private PersistentBuffer _background = new PersistentBuffer();
private readonly PersistentBuffer _main = new();
private readonly PersistentBuffer _background = new();
private Dictionary<BufferHandle, IntPtr> _maps = new Dictionary<BufferHandle, IntPtr>();
private readonly Dictionary<BufferHandle, IntPtr> _maps = new();
public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main;
@@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.OpenGL
return _dataMap;
}
private void Sync()
private static void Sync()
{
GL.MemoryBarrier(MemoryBarrierFlags.ClientMappedBufferBarrierBit);
@@ -133,7 +133,7 @@ namespace Ryujinx.Graphics.OpenGL
Sync();
return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size).Slice(offset);
return new ReadOnlySpan<byte>(_bufferMap.ToPointer(), size)[offset..];
}
public unsafe ReadOnlySpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)

View File

@@ -44,11 +44,11 @@ namespace Ryujinx.Graphics.OpenGL
private CounterQueueEvent _activeConditionalRender;
private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private Vector4<float>[] _renderScale = new Vector4<float>[73];
private readonly Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount];
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
private int _fragmentScaleCount;
private (TextureBase, Format)[] _images;
private readonly (TextureBase, Format)[] _images;
private TextureBase _unit0Texture;
private Sampler _unit0Sampler;
@@ -260,7 +260,7 @@ namespace Ryujinx.Graphics.OpenGL
PostDraw();
}
private void DrawQuadsImpl(
private static void DrawQuadsImpl(
int vertexCount,
int instanceCount,
int firstVertex,
@@ -285,7 +285,7 @@ namespace Ryujinx.Graphics.OpenGL
quadsCount);
}
private void DrawQuadStripImpl(
private static void DrawQuadStripImpl(
int vertexCount,
int instanceCount,
int firstVertex,
@@ -366,8 +366,12 @@ namespace Ryujinx.Graphics.OpenGL
switch (_elementsType)
{
case DrawElementsType.UnsignedShort: indexElemSize = 2; break;
case DrawElementsType.UnsignedInt: indexElemSize = 4; break;
case DrawElementsType.UnsignedShort:
indexElemSize = 2;
break;
case DrawElementsType.UnsignedInt:
indexElemSize = 4;
break;
}
IntPtr indexBaseOffset = _indexBaseOffset + firstIndex * indexElemSize;
@@ -1471,7 +1475,7 @@ namespace Ryujinx.Graphics.OpenGL
GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);
}
private void SetBuffers(ReadOnlySpan<BufferAssignment> buffers, bool isStorage)
private static void SetBuffers(ReadOnlySpan<BufferAssignment> buffers, bool isStorage)
{
BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer;
@@ -1700,12 +1704,10 @@ namespace Ryujinx.Graphics.OpenGL
}
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
{
if (value is CounterQueueEvent)
{
// Compare an event and a constant value.
CounterQueueEvent evt = (CounterQueueEvent)value;
if (value is CounterQueueEvent evt)
{
// Easy host conditional rendering when the check matches what GL can do:
// - Event is of type samples passed.
// - Result is not a combination of multiple queries.

View File

@@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.OpenGL
if (log.Length > MaxShaderLogLength)
{
log = log.Substring(0, MaxShaderLogLength) + "...";
log = log[..MaxShaderLogLength] + "...";
}
Logger.Warning?.Print(LogClass.Gpu, $"Shader linking failed: \n{log}");

View File

@@ -14,9 +14,9 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public int Query { get; }
private int _buffer;
private IntPtr _bufferMap;
private QueryTarget _type;
private readonly int _buffer;
private readonly IntPtr _bufferMap;
private readonly QueryTarget _type;
public BufferedQuery(QueryTarget type)
{
@@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
}
}
private bool WaitingForValue(long data)
private static bool WaitingForValue(long data)
{
return data == DefaultValue ||
((ulong)data & HighMask) == (unchecked((ulong)DefaultValue) & HighMask);

View File

@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly Pipeline _pipeline;
private Queue<CounterQueueEvent> _events = new Queue<CounterQueueEvent>();
private readonly Queue<CounterQueueEvent> _events = new();
private CounterQueueEvent _current;
private ulong _accumulatedCounter;
@@ -23,12 +23,12 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private readonly object _lock = new();
private Queue<BufferedQuery> _queryPool;
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
private AutoResetEvent _wakeSignal = new AutoResetEvent(false);
private AutoResetEvent _eventConsumed = new AutoResetEvent(false);
private readonly Queue<BufferedQuery> _queryPool;
private readonly AutoResetEvent _queuedEvent = new(false);
private readonly AutoResetEvent _wakeSignal = new(false);
private readonly AutoResetEvent _eventConsumed = new(false);
private Thread _consumerThread;
private readonly Thread _consumerThread;
internal CounterQueue(Pipeline pipeline, CounterType type)
{
@@ -148,14 +148,13 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private static QueryTarget GetTarget(CounterType type)
{
switch (type)
return type switch
{
case CounterType.SamplesPassed: return QueryTarget.SamplesPassed;
case CounterType.PrimitivesGenerated: return QueryTarget.PrimitivesGenerated;
case CounterType.TransformFeedbackPrimitivesWritten: return QueryTarget.TransformFeedbackPrimitivesWritten;
}
return QueryTarget.SamplesPassed;
CounterType.SamplesPassed => QueryTarget.SamplesPassed,
CounterType.PrimitivesGenerated => QueryTarget.PrimitivesGenerated,
CounterType.TransformFeedbackPrimitivesWritten => QueryTarget.TransformFeedbackPrimitivesWritten,
_ => QueryTarget.SamplesPassed,
};
}
public void Flush(bool blocking)

View File

@@ -18,8 +18,8 @@ namespace Ryujinx.Graphics.OpenGL.Queries
public ulong DrawIndex { get; }
private CounterQueue _queue;
private BufferedQuery _counter;
private readonly CounterQueue _queue;
private readonly BufferedQuery _counter;
private bool _hostAccessReserved = false;
private int _refCount = 1; // Starts with a reference from the counter queue.

View File

@@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
{
class Counters : IDisposable
{
private CounterQueue[] _counterQueues;
private readonly CounterQueue[] _counterQueues;
public Counters()
{

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.OpenGL
private const int DisposedLiveFrames = 2;
private readonly object _lock = new();
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new Dictionary<TextureCreateInfo, List<DisposedTexture>>();
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new();
/// <summary>
/// Add a texture that is not being used anymore to the resource pool to be used later.
@@ -32,8 +32,7 @@ namespace Ryujinx.Graphics.OpenGL
{
lock (_lock)
{
List<DisposedTexture> list;
if (!_textures.TryGetValue(view.Info, out list))
if (!_textures.TryGetValue(view.Info, out List<DisposedTexture> list))
{
list = new List<DisposedTexture>();
_textures.Add(view.Info, list);
@@ -59,8 +58,7 @@ namespace Ryujinx.Graphics.OpenGL
{
lock (_lock)
{
List<DisposedTexture> list;
if (!_textures.TryGetValue(info, out list))
if (!_textures.TryGetValue(info, out List<DisposedTexture> list))
{
return null;
}

View File

@@ -15,13 +15,13 @@ namespace Ryujinx.Graphics.OpenGL
}
private ulong _firstHandle = 0;
private ClientWaitSyncFlags _syncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit;
private static ClientWaitSyncFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit;
private List<SyncHandle> _handles = new List<SyncHandle>();
private readonly List<SyncHandle> _handles = new();
public void Create(ulong id)
{
SyncHandle handle = new SyncHandle
SyncHandle handle = new()
{
ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None)
@@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.OpenGL
if (handle.ID > lastHandle)
{
WaitSyncStatus syncResult = GL.ClientWaitSync(handle.Handle, _syncFlags, 0);
WaitSyncStatus syncResult = GL.ClientWaitSync(handle.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled)
{
@@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.OpenGL
return;
}
WaitSyncStatus syncResult = GL.ClientWaitSync(result.Handle, _syncFlags, 1000000000);
WaitSyncStatus syncResult = GL.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
if (syncResult == WaitSyncStatus.TimeoutExpired)
{
@@ -123,9 +123,12 @@ namespace Ryujinx.Graphics.OpenGL
first = _handles.FirstOrDefault();
}
if (first == null) break;
if (first == null)
{
break;
}
WaitSyncStatus syncResult = GL.ClientWaitSync(first.Handle, _syncFlags, 0);
WaitSyncStatus syncResult = GL.ClientWaitSync(first.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled)
{
@@ -140,7 +143,8 @@ namespace Ryujinx.Graphics.OpenGL
first.Handle = IntPtr.Zero;
}
}
} else
}
else
{
// This sync handle and any following have not been reached yet.
break;

View File

@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
private uint _vertexBuffersLimited;
private BufferRange _indexBuffer;
private BufferHandle _tempIndexBuffer;
private readonly BufferHandle _tempIndexBuffer;
private BufferHandle _tempVertexBuffer;
private int _tempVertexBufferSize;

View File

@@ -375,7 +375,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_scalingFilter is not FsrScalingFilter)
{
_scalingFilter?.Dispose();
_scalingFilter = new FsrScalingFilter(_renderer, _antiAliasing);
_scalingFilter = new FsrScalingFilter(_renderer);
}
_isLinear = false;
_scalingFilter.Level = _scalingFilterLevel;

View File

@@ -426,6 +426,86 @@ namespace Ryujinx.Tests.Cpu
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("VCVT.I32.F32 <Vd>, <Vm>, #<fbits>")]
public void Vcvt_V_Fixed_F32_I32([Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 1u, 2u, 3u)] uint vm,
[ValueSource(nameof(_1S_F_))][Random(RndCnt)] ulong s0,
[ValueSource(nameof(_1S_F_))][Random(RndCnt)] ulong s1,
[ValueSource(nameof(_1S_F_))][Random(RndCnt)] ulong s2,
[ValueSource(nameof(_1S_F_))][Random(RndCnt)] ulong s3,
[Random(32u, 63u, 1)] uint fixImm,
[Values] bool unsigned,
[Values] bool q)
{
uint opcode = 0xF2800F10u; // VCVT.U32.F32 D0, D0, #0
if (q)
{
opcode |= 1 << 6;
vm <<= 1;
vd <<= 1;
}
if (unsigned)
{
opcode |= 1 << 24;
}
opcode |= ((vm & 0x10) << 1);
opcode |= ((vm & 0xf) << 0);
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
opcode |= (fixImm & 0x3f) << 16;
var v0 = new V128((uint)s0, (uint)s1, (uint)s2, (uint)s3);
SingleOpcode(opcode, v0: v0);
CompareAgainstUnicorn();
}
[Test, Pairwise, Description("VCVT.F32.I32 <Vd>, <Vm>, #<fbits>")]
public void Vcvt_V_Fixed_I32_F32([Values(0u, 1u, 2u, 3u)] uint vd,
[Values(0u, 1u, 2u, 3u)] uint vm,
[ValueSource(nameof(_1S_))][Random(RndCnt)] uint s0,
[ValueSource(nameof(_1S_))][Random(RndCnt)] uint s1,
[ValueSource(nameof(_1S_))][Random(RndCnt)] uint s2,
[ValueSource(nameof(_1S_))][Random(RndCnt)] uint s3,
[Range(32u, 63u, 1)] uint fixImm,
[Values] bool unsigned,
[Values] bool q)
{
uint opcode = 0xF2800E10u; // VCVT.F32.U32 D0, D0, #0
if (q)
{
opcode |= 1 << 6;
vm <<= 1;
vd <<= 1;
}
if (unsigned)
{
opcode |= 1 << 24;
}
opcode |= ((vm & 0x10) << 1);
opcode |= ((vm & 0xf) << 0);
opcode |= ((vd & 0x10) << 18);
opcode |= ((vd & 0xf) << 12);
opcode |= (fixImm & 0x3f) << 16;
var v0 = new V128(s0, s1, s2, s3);
SingleOpcode(opcode, v0: v0);
CompareAgainstUnicorn();
}
#endif
}
}