diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index ffb5d5f8bd..68be1f5e0d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -23,7 +23,7 @@ body: attributes: label: Log file description: A log file will help our developers to better diagnose and fix the issue. - placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. They can also be accessed by opening Ryujinx, then going to File > Open Logs Folder. You can drag and drop the log on to the text area (do not copy paste). + placeholder: Logs files can be found under "Logs" folder in Ryujinx program folder. You can drag and drop the log on to the text area validations: required: true - type: input @@ -83,4 +83,4 @@ body: - Additional info about your environment: - Any other information relevant to your issue. validations: - required: false + required: false \ No newline at end of file diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs index 33f61e6a51..09f415d20c 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs @@ -1,11 +1,9 @@ using Ryujinx.Audio.Renderer.Dsp.Effect; using Ryujinx.Audio.Renderer.Dsp.State; -using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Parameter.Effect; using Ryujinx.Audio.Renderer.Server.Effect; using System; using System.Diagnostics; -using System.Runtime.InteropServices; namespace Ryujinx.Audio.Renderer.Dsp.Command { @@ -23,20 +21,18 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public CompressorParameter Parameter => _parameter; public Memory State { get; } - public Memory ResultState { get; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } public bool IsEffectEnabled { get; } private CompressorParameter _parameter; - public CompressorCommand(uint bufferOffset, CompressorParameter parameter, Memory state, Memory resultState, bool isEnabled, int nodeId) + public CompressorCommand(uint bufferOffset, CompressorParameter parameter, Memory state, bool isEnabled, int nodeId) { Enabled = true; NodeId = nodeId; _parameter = parameter; State = state; - ResultState = resultState; IsEffectEnabled = isEnabled; @@ -75,16 +71,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command if (IsEffectEnabled && _parameter.IsChannelCountValid()) { - if (!ResultState.IsEmpty && _parameter.StatisticsReset) - { - ref CompressorStatistics statistics = ref MemoryMarshal.Cast(ResultState.Span[0].SpecificData)[0]; - - statistics.Reset(_parameter.ChannelCount); - } - - Span inputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; - Span outputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; - Span channelInput = stackalloc float[_parameter.ChannelCount]; + Span inputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; + Span outputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; + Span channelInput = stackalloc float[Parameter.ChannelCount]; ExponentialMovingAverage inputMovingAverage = state.InputMovingAverage; float unknown4 = state.Unknown4; ExponentialMovingAverage compressionGainAverage = state.CompressionGainAverage; @@ -103,8 +92,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command channelInput[channelIndex] = *((float*)inputBuffers[channelIndex] + sampleIndex); } - float mean = FloatingPointHelper.MeanSquare(channelInput); - float newMean = inputMovingAverage.Update(mean, _parameter.InputGain); + float newMean = inputMovingAverage.Update(FloatingPointHelper.MeanSquare(channelInput), _parameter.InputGain); float y = FloatingPointHelper.Log10(newMean) * 10.0f; float z = 1.0f; @@ -123,7 +111,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command if (y >= state.Unknown14) { - tmpGain = ((1.0f / _parameter.Ratio) - 1.0f) * (y - _parameter.Threshold); + tmpGain = ((1.0f / Parameter.Ratio) - 1.0f) * (y - Parameter.Threshold); } else { @@ -138,7 +126,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command if ((unknown4 - z) <= 0.08f) { - compressionEmaAlpha = _parameter.ReleaseCoefficient; + compressionEmaAlpha = Parameter.ReleaseCoefficient; if ((unknown4 - z) >= -0.08f) { @@ -152,31 +140,18 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } else { - compressionEmaAlpha = _parameter.AttackCoefficient; + compressionEmaAlpha = Parameter.AttackCoefficient; } float compressionGain = compressionGainAverage.Update(z, compressionEmaAlpha); - for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++) + for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++) { *((float*)outputBuffers[channelIndex] + sampleIndex) = channelInput[channelIndex] * compressionGain * state.OutputGain; } unknown4 = unknown4New; previousCompressionEmaAlpha = compressionEmaAlpha; - - if (!ResultState.IsEmpty) - { - ref CompressorStatistics statistics = ref MemoryMarshal.Cast(ResultState.Span[0].SpecificData)[0]; - - statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain); - statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean); - - for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++) - { - statistics.LastSamples[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f)); - } - } } state.InputMovingAverage = inputMovingAverage; @@ -186,7 +161,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } else { - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { if (InputBufferIndices[i] != OutputBufferIndices[i]) { diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs index 06e9321997..3ba0b5884d 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs @@ -38,10 +38,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { - InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]); - OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]); + InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]); + OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]); } } @@ -51,11 +51,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command if (IsEffectEnabled) { - if (_parameter.Status == UsageState.Invalid) + if (Parameter.Status == UsageState.Invalid) { state = new LimiterState(ref _parameter, WorkBuffer); } - else if (_parameter.Status == UsageState.New) + else if (Parameter.Status == UsageState.New) { LimiterState.UpdateParameter(ref _parameter); } @@ -66,56 +66,56 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command private unsafe void ProcessLimiter(CommandList context, ref LimiterState state) { - Debug.Assert(_parameter.IsChannelCountValid()); + Debug.Assert(Parameter.IsChannelCountValid()); - if (IsEffectEnabled && _parameter.IsChannelCountValid()) + if (IsEffectEnabled && Parameter.IsChannelCountValid()) { - Span inputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; - Span outputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; + Span inputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; + Span outputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { inputBuffers[i] = context.GetBufferPointer(InputBufferIndices[i]); outputBuffers[i] = context.GetBufferPointer(OutputBufferIndices[i]); } - for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++) + for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++) { for (int sampleIndex = 0; sampleIndex < context.SampleCount; sampleIndex++) { float rawInputSample = *((float*)inputBuffers[channelIndex] + sampleIndex); - float inputSample = (rawInputSample / short.MaxValue) * _parameter.InputGain; + float inputSample = (rawInputSample / short.MaxValue) * Parameter.InputGain; float sampleInputMax = Math.Abs(inputSample); - float inputCoefficient = _parameter.ReleaseCoefficient; + float inputCoefficient = Parameter.ReleaseCoefficient; if (sampleInputMax > state.DetectorAverage[channelIndex].Read()) { - inputCoefficient = _parameter.AttackCoefficient; + inputCoefficient = Parameter.AttackCoefficient; } float detectorValue = state.DetectorAverage[channelIndex].Update(sampleInputMax, inputCoefficient); float attenuation = 1.0f; - if (detectorValue > _parameter.Threshold) + if (detectorValue > Parameter.Threshold) { - attenuation = _parameter.Threshold / detectorValue; + attenuation = Parameter.Threshold / detectorValue; } - float outputCoefficient = _parameter.ReleaseCoefficient; + float outputCoefficient = Parameter.ReleaseCoefficient; if (state.CompressionGainAverage[channelIndex].Read() > attenuation) { - outputCoefficient = _parameter.AttackCoefficient; + outputCoefficient = Parameter.AttackCoefficient; } float compressionGain = state.CompressionGainAverage[channelIndex].Update(attenuation, outputCoefficient); - ref float delayedSample = ref state.DelayedSampleBuffer[channelIndex * _parameter.DelayBufferSampleCountMax + state.DelayedSampleBufferPosition[channelIndex]]; + ref float delayedSample = ref state.DelayedSampleBuffer[channelIndex * Parameter.DelayBufferSampleCountMax + state.DelayedSampleBufferPosition[channelIndex]]; - float outputSample = delayedSample * compressionGain * _parameter.OutputGain; + float outputSample = delayedSample * compressionGain * Parameter.OutputGain; *((float*)outputBuffers[channelIndex] + sampleIndex) = outputSample * short.MaxValue; @@ -123,16 +123,16 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command state.DelayedSampleBufferPosition[channelIndex]++; - while (state.DelayedSampleBufferPosition[channelIndex] >= _parameter.DelayBufferSampleCountMin) + while (state.DelayedSampleBufferPosition[channelIndex] >= Parameter.DelayBufferSampleCountMin) { - state.DelayedSampleBufferPosition[channelIndex] -= _parameter.DelayBufferSampleCountMin; + state.DelayedSampleBufferPosition[channelIndex] -= Parameter.DelayBufferSampleCountMin; } } } } else { - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { if (InputBufferIndices[i] != OutputBufferIndices[i]) { diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs index ed0538c061..f6e1654dd3 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs @@ -49,10 +49,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { - InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]); - OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]); + InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]); + OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]); } } @@ -62,11 +62,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command if (IsEffectEnabled) { - if (_parameter.Status == UsageState.Invalid) + if (Parameter.Status == UsageState.Invalid) { state = new LimiterState(ref _parameter, WorkBuffer); } - else if (_parameter.Status == UsageState.New) + else if (Parameter.Status == UsageState.New) { LimiterState.UpdateParameter(ref _parameter); } @@ -77,63 +77,63 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command private unsafe void ProcessLimiter(CommandList context, ref LimiterState state) { - Debug.Assert(_parameter.IsChannelCountValid()); + Debug.Assert(Parameter.IsChannelCountValid()); - if (IsEffectEnabled && _parameter.IsChannelCountValid()) + if (IsEffectEnabled && Parameter.IsChannelCountValid()) { - if (!ResultState.IsEmpty && _parameter.StatisticsReset) + if (!ResultState.IsEmpty && Parameter.StatisticsReset) { ref LimiterStatistics statistics = ref MemoryMarshal.Cast(ResultState.Span[0].SpecificData)[0]; statistics.Reset(); } - Span inputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; - Span outputBuffers = stackalloc IntPtr[_parameter.ChannelCount]; + Span inputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; + Span outputBuffers = stackalloc IntPtr[Parameter.ChannelCount]; - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { inputBuffers[i] = context.GetBufferPointer(InputBufferIndices[i]); outputBuffers[i] = context.GetBufferPointer(OutputBufferIndices[i]); } - for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++) + for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++) { for (int sampleIndex = 0; sampleIndex < context.SampleCount; sampleIndex++) { float rawInputSample = *((float*)inputBuffers[channelIndex] + sampleIndex); - float inputSample = (rawInputSample / short.MaxValue) * _parameter.InputGain; + float inputSample = (rawInputSample / short.MaxValue) * Parameter.InputGain; float sampleInputMax = Math.Abs(inputSample); - float inputCoefficient = _parameter.ReleaseCoefficient; + float inputCoefficient = Parameter.ReleaseCoefficient; if (sampleInputMax > state.DetectorAverage[channelIndex].Read()) { - inputCoefficient = _parameter.AttackCoefficient; + inputCoefficient = Parameter.AttackCoefficient; } float detectorValue = state.DetectorAverage[channelIndex].Update(sampleInputMax, inputCoefficient); float attenuation = 1.0f; - if (detectorValue > _parameter.Threshold) + if (detectorValue > Parameter.Threshold) { - attenuation = _parameter.Threshold / detectorValue; + attenuation = Parameter.Threshold / detectorValue; } - float outputCoefficient = _parameter.ReleaseCoefficient; + float outputCoefficient = Parameter.ReleaseCoefficient; if (state.CompressionGainAverage[channelIndex].Read() > attenuation) { - outputCoefficient = _parameter.AttackCoefficient; + outputCoefficient = Parameter.AttackCoefficient; } float compressionGain = state.CompressionGainAverage[channelIndex].Update(attenuation, outputCoefficient); - ref float delayedSample = ref state.DelayedSampleBuffer[channelIndex * _parameter.DelayBufferSampleCountMax + state.DelayedSampleBufferPosition[channelIndex]]; + ref float delayedSample = ref state.DelayedSampleBuffer[channelIndex * Parameter.DelayBufferSampleCountMax + state.DelayedSampleBufferPosition[channelIndex]]; - float outputSample = delayedSample * compressionGain * _parameter.OutputGain; + float outputSample = delayedSample * compressionGain * Parameter.OutputGain; *((float*)outputBuffers[channelIndex] + sampleIndex) = outputSample * short.MaxValue; @@ -141,9 +141,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command state.DelayedSampleBufferPosition[channelIndex]++; - while (state.DelayedSampleBufferPosition[channelIndex] >= _parameter.DelayBufferSampleCountMin) + while (state.DelayedSampleBufferPosition[channelIndex] >= Parameter.DelayBufferSampleCountMin) { - state.DelayedSampleBufferPosition[channelIndex] -= _parameter.DelayBufferSampleCountMin; + state.DelayedSampleBufferPosition[channelIndex] -= Parameter.DelayBufferSampleCountMin; } if (!ResultState.IsEmpty) @@ -158,7 +158,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } else { - for (int i = 0; i < _parameter.ChannelCount; i++) + for (int i = 0; i < Parameter.ChannelCount; i++) { if (InputBufferIndices[i] != OutputBufferIndices[i]) { diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs index c00118e49a..b403f13703 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorParameter.cs @@ -90,16 +90,9 @@ namespace Ryujinx.Audio.Renderer.Parameter.Effect public bool MakeupGainEnabled; /// - /// Indicate if the compressor effect should output statistics. + /// Reserved/padding. /// - [MarshalAs(UnmanagedType.I1)] - public bool StatisticsEnabled; - - /// - /// Indicate to the DSP that the user did a statistics reset. - /// - [MarshalAs(UnmanagedType.I1)] - public bool StatisticsReset; + private Array2 _reserved; /// /// Check if the is valid. diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorStatistics.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorStatistics.cs deleted file mode 100644 index 65335e2d99..0000000000 --- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/CompressorStatistics.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Ryujinx.Common.Memory; -using System.Runtime.InteropServices; - -namespace Ryujinx.Audio.Renderer.Parameter.Effect -{ - /// - /// Effect result state for . - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct CompressorStatistics - { - /// - /// Maximum input mean value since last reset. - /// - public float MaximumMean; - - /// - /// Minimum output gain since last reset. - /// - public float MinimumGain; - - /// - /// Last processed input sample, per channel. - /// - public Array6 LastSamples; - - /// - /// Reset the statistics. - /// - /// Number of channels to reset. - public void Reset(ushort channelCount) - { - MaximumMean = 0.0f; - MinimumGain = 1.0f; - LastSamples.AsSpan()[..channelCount].Clear(); - } - } -} diff --git a/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs index 7ee49f11a6..807232f208 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs @@ -28,11 +28,6 @@ namespace Ryujinx.Audio.Renderer.Parameter /// bool IsUsed { get; } - /// - /// Set to true to force resetting the previous mix volumes. - /// - bool ResetPrevVolume { get; } - /// /// Mix buffer volumes. /// diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs index f346efcb05..029c001ea9 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs @@ -37,16 +37,10 @@ namespace Ryujinx.Audio.Renderer.Parameter [MarshalAs(UnmanagedType.I1)] public bool IsUsed; - /// - /// Set to true to force resetting the previous mix volumes. - /// - [MarshalAs(UnmanagedType.I1)] - public bool ResetPrevVolume; - /// /// Reserved/padding. /// - private unsafe fixed byte _reserved[2]; + private unsafe fixed byte _reserved[3]; [StructLayout(LayoutKind.Sequential, Size = sizeof(float) * Constants.MixBufferCountMax, Pack = 1)] private struct MixArray { } @@ -64,7 +58,6 @@ namespace Ryujinx.Audio.Renderer.Parameter readonly Array2 ISplitterDestinationInParameter.BiquadFilters => default; readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed; - readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume; /// /// The expected constant of any input header. diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs index 1d867919d4..312be8b707 100644 --- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs @@ -42,16 +42,10 @@ namespace Ryujinx.Audio.Renderer.Parameter [MarshalAs(UnmanagedType.I1)] public bool IsUsed; - /// - /// Set to true to force resetting the previous mix volumes. - /// - [MarshalAs(UnmanagedType.I1)] - public bool ResetPrevVolume; - /// /// Reserved/padding. /// - private unsafe fixed byte _reserved[10]; + private unsafe fixed byte _reserved[11]; [StructLayout(LayoutKind.Sequential, Size = sizeof(float) * Constants.MixBufferCountMax, Pack = 1)] private struct MixArray { } @@ -69,7 +63,6 @@ namespace Ryujinx.Audio.Renderer.Parameter readonly Array2 ISplitterDestinationInParameter.BiquadFilters => BiquadFilters; readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed; - readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume; /// /// The expected constant of any input header. diff --git a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs index f725eb9f3e..32c7de6cfb 100644 --- a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs @@ -108,18 +108,10 @@ namespace Ryujinx.Audio.Renderer.Server /// This was added in system update 17.0.0 public const int Revision12 = 12 << 24; - /// - /// REV13: - /// The compressor effect can now output statistics. - /// Splitter destinations now explicitly reset the previous mix volume, instead of doing so on first use. - /// - /// This was added in system update 18.0.0 - public const int Revision13 = 13 << 24; - /// /// Last revision supported by the implementation. /// - public const int LastRevision = Revision13; + public const int LastRevision = Revision12; /// /// Target revision magic supported by the implementation. @@ -392,15 +384,6 @@ namespace Ryujinx.Audio.Renderer.Server return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision12); } - /// - /// Check if the audio renderer should support explicit previous mix volume reset on splitter. - /// - /// True if the audio renderer support explicit previous mix volume reset on splitter - public bool IsSplitterPrevVolumeResetSupported() - { - return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision13); - } - /// /// Get the version of the . /// diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs index 4c353b37e1..702f05462f 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs @@ -583,20 +583,11 @@ namespace Ryujinx.Audio.Renderer.Server } } - /// - /// Generate a new . - /// - /// The target buffer offset. - /// The compressor parameter. - /// The compressor state. - /// The DSP effect result state. - /// Set to true if the effect should be active. - /// The node id associated to this command. - public void GenerateCompressorEffect(uint bufferOffset, CompressorParameter parameter, Memory state, Memory effectResultState, bool isEnabled, int nodeId) + public void GenerateCompressorEffect(uint bufferOffset, CompressorParameter parameter, Memory state, bool isEnabled, int nodeId) { if (parameter.IsChannelCountValid()) { - CompressorCommand command = new(bufferOffset, parameter, state, effectResultState, isEnabled, nodeId); + CompressorCommand command = new(bufferOffset, parameter, state, isEnabled, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs index 0b789537a7..d798230c1d 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs @@ -735,26 +735,14 @@ namespace Ryujinx.Audio.Renderer.Server } } - private void GenerateCompressorEffect(uint bufferOffset, CompressorEffect effect, int nodeId, int effectId) + private void GenerateCompressorEffect(uint bufferOffset, CompressorEffect effect, int nodeId) { Debug.Assert(effect.Type == EffectType.Compressor); - Memory dspResultState; - - if (effect.Parameter.StatisticsEnabled) - { - dspResultState = _effectContext.GetDspStateMemory(effectId); - } - else - { - dspResultState = Memory.Empty; - } - _commandBuffer.GenerateCompressorEffect( bufferOffset, effect.Parameter, effect.State, - dspResultState, effect.IsEnabled, nodeId); } @@ -807,7 +795,7 @@ namespace Ryujinx.Audio.Renderer.Server GenerateCaptureEffect(mix.BufferOffset, (CaptureBufferEffect)effect, nodeId); break; case EffectType.Compressor: - GenerateCompressorEffect(mix.BufferOffset, (CompressorEffect)effect, nodeId, effectId); + GenerateCompressorEffect(mix.BufferOffset, (CompressorEffect)effect, nodeId); break; default: throw new NotImplementedException($"Unsupported effect type {effect.Type}"); diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs index bc9ba073d6..06f135a886 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs @@ -169,28 +169,14 @@ namespace Ryujinx.Audio.Renderer.Server { if (command.Enabled) { - if (command.Parameter.StatisticsEnabled) + return command.Parameter.ChannelCount switch { - return command.Parameter.ChannelCount switch - { - 1 => 22100, - 2 => 33211, - 4 => 41587, - 6 => 58819, - _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), - }; - } - else - { - return command.Parameter.ChannelCount switch - { - 1 => 19052, - 2 => 29852, - 4 => 37904, - 6 => 55020, - _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), - }; - } + 1 => 34431, + 2 => 44253, + 4 => 63827, + 6 => 83361, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } return command.Parameter.ChannelCount switch @@ -205,28 +191,14 @@ namespace Ryujinx.Audio.Renderer.Server if (command.Enabled) { - if (command.Parameter.StatisticsEnabled) + return command.Parameter.ChannelCount switch { - return command.Parameter.ChannelCount switch - { - 1 => 32518, - 2 => 49102, - 4 => 61685, - 6 => 87250, - _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), - }; - } - else - { - return command.Parameter.ChannelCount switch - { - 1 => 27963, - 2 => 44016, - 4 => 56183, - 6 => 81862, - _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), - }; - } + 1 => 51095, + 2 => 65693, + 4 => 95383, + 6 => 124510, + _ => throw new NotImplementedException($"{command.Parameter.ChannelCount}"), + }; } return command.Parameter.ChannelCount switch diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs index de0f44e475..eff60e7da8 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs @@ -62,19 +62,6 @@ namespace Ryujinx.Audio.Renderer.Server.Effect UpdateUsageStateForCommandGeneration(); Parameter.Status = UsageState.Enabled; - Parameter.StatisticsReset = false; - } - - public override void InitializeResultState(ref EffectResultState state) - { - ref CompressorStatistics statistics = ref MemoryMarshal.Cast(state.SpecificData)[0]; - - statistics.Reset(Parameter.ChannelCount); - } - - public override void UpdateResultState(ref EffectResultState destState, ref EffectResultState srcState) - { - destState = srcState; } } } diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs index 6dddb43158..a7b82a6bdc 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs @@ -51,11 +51,6 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter /// public bool IsBugFixed { get; private set; } - /// - /// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use. - /// - public bool IsSplitterPrevVolumeResetSupported { get; private set; } - /// /// Initialize . /// @@ -144,8 +139,6 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter } } - IsSplitterPrevVolumeResetSupported = behaviourContext.IsSplitterPrevVolumeResetSupported(); - SplitterState.InitializeSplitters(splitters.Span); Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourContext.IsSplitterBugFixed()); @@ -284,7 +277,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter { SplitterDestination destination = GetDestination(parameter.Id); - destination.Update(parameter, IsSplitterPrevVolumeResetSupported); + destination.Update(parameter); } return true; diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs index 1a46d41fde..36dfa5e413 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs @@ -184,16 +184,15 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter /// Update the splitter destination data from user parameter. /// /// The user parameter. - /// Indicates that the audio renderer revision in use supports explicitly resetting the volume. - public void Update(in T parameter, bool isPrevVolumeResetSupported) where T : ISplitterDestinationInParameter + public void Update(in T parameter) where T : ISplitterDestinationInParameter { if (Unsafe.IsNullRef(ref _v2)) { - _v1.Update(parameter, isPrevVolumeResetSupported); + _v1.Update(parameter); } else { - _v2.Update(parameter, isPrevVolumeResetSupported); + _v2.Update(parameter); } } diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion1.cs index ce8f33685f..5d2b8fb0fe 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion1.cs @@ -93,8 +93,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter /// Update the from user parameter. /// /// The user parameter. - /// Indicates that the audio renderer revision in use supports explicitly resetting the volume. - public void Update(in T parameter, bool isPrevVolumeResetSupported) where T : ISplitterDestinationInParameter + public void Update(in T parameter) where T : ISplitterDestinationInParameter { Debug.Assert(Id == parameter.Id); @@ -104,8 +103,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter parameter.MixBufferVolume.CopyTo(MixBufferVolume); - bool resetPrevVolume = isPrevVolumeResetSupported ? parameter.ResetPrevVolume : !IsUsed && parameter.IsUsed; - if (resetPrevVolume) + if (!IsUsed && parameter.IsUsed) { MixBufferVolume.CopyTo(PreviousMixBufferVolume); diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs index 5f96ef3aa5..f9487909d4 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs @@ -98,8 +98,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter /// Update the from user parameter. /// /// The user parameter. - /// Indicates that the audio renderer revision in use supports explicitly resetting the volume. - public void Update(in T parameter, bool isPrevVolumeResetSupported) where T : ISplitterDestinationInParameter + public void Update(in T parameter) where T : ISplitterDestinationInParameter { Debug.Assert(Id == parameter.Id); @@ -111,8 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter _biquadFilters = parameter.BiquadFilters; - bool resetPrevVolume = isPrevVolumeResetSupported ? parameter.ResetPrevVolume : !IsUsed && parameter.IsUsed; - if (resetPrevVolume) + if (!IsUsed && parameter.IsUsed) { MixBufferVolume.CopyTo(PreviousMixBufferVolume); diff --git a/src/Ryujinx.Graphics.GAL/Capabilities.cs b/src/Ryujinx.Graphics.GAL/Capabilities.cs index 1eec80e51b..a5c6eb5c8e 100644 --- a/src/Ryujinx.Graphics.GAL/Capabilities.cs +++ b/src/Ryujinx.Graphics.GAL/Capabilities.cs @@ -71,8 +71,6 @@ namespace Ryujinx.Graphics.GAL public readonly int GatherBiasPrecision; - public readonly ulong MaximumGpuMemory; - public Capabilities( TargetApi api, string vendorName, @@ -133,8 +131,7 @@ namespace Ryujinx.Graphics.GAL int shaderSubgroupSize, int storageBufferOffsetAlignment, int textureBufferOffsetAlignment, - int gatherBiasPrecision, - ulong maximumGpuMemory) + int gatherBiasPrecision) { Api = api; VendorName = vendorName; @@ -196,7 +193,6 @@ namespace Ryujinx.Graphics.GAL StorageBufferOffsetAlignment = storageBufferOffsetAlignment; TextureBufferOffsetAlignment = textureBufferOffsetAlignment; GatherBiasPrecision = gatherBiasPrecision; - MaximumGpuMemory = maximumGpuMemory; } } } diff --git a/src/Ryujinx.Graphics.GAL/ITexture.cs b/src/Ryujinx.Graphics.GAL/ITexture.cs index 2aa4053ff2..2d9c6b7990 100644 --- a/src/Ryujinx.Graphics.GAL/ITexture.cs +++ b/src/Ryujinx.Graphics.GAL/ITexture.cs @@ -1,4 +1,4 @@ -using Ryujinx.Common.Memory; +using System.Buffers; namespace Ryujinx.Graphics.GAL { @@ -18,30 +18,30 @@ namespace Ryujinx.Graphics.GAL PinnedSpan GetData(int layer, int level); /// - /// Sets the texture data. The data passed as a will be disposed when + /// Sets the texture data. The data passed as a will be disposed when /// the operation completes. /// /// Texture data bytes - void SetData(MemoryOwner data); + void SetData(IMemoryOwner data); /// - /// Sets the texture data. The data passed as a will be disposed when + /// Sets the texture data. The data passed as a will be disposed when /// the operation completes. /// /// Texture data bytes /// Target layer /// Target level - void SetData(MemoryOwner data, int layer, int level); + void SetData(IMemoryOwner data, int layer, int level); /// - /// Sets the texture data. The data passed as a will be disposed when + /// Sets the texture data. The data passed as a will be disposed when /// the operation completes. /// /// Texture data bytes /// Target layer /// Target level /// Target sub-region of the texture to update - void SetData(MemoryOwner data, int layer, int level, Rectangle region); + void SetData(IMemoryOwner data, int layer, int level, Rectangle region); void SetStorage(BufferRange buffer); diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs index 4449566a7e..3aba004dff 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataCommand.cs @@ -1,6 +1,6 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; +using System.Buffers; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { @@ -8,9 +8,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { public readonly CommandType CommandType => CommandType.TextureSetData; private TableRef _texture; - private TableRef> _data; + private TableRef> _data; - public void Set(TableRef texture, TableRef> data) + public void Set(TableRef texture, TableRef> data) { _texture = texture; _data = data; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs index 3619149e9c..7ad709a757 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceCommand.cs @@ -1,6 +1,6 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; +using System.Buffers; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { @@ -8,11 +8,11 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { public readonly CommandType CommandType => CommandType.TextureSetDataSlice; private TableRef _texture; - private TableRef> _data; + private TableRef> _data; private int _layer; private int _level; - public void Set(TableRef texture, TableRef> data, int layer, int level) + public void Set(TableRef texture, TableRef> data, int layer, int level) { _texture = texture; _data = data; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceRegionCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceRegionCommand.cs index 6c6a536360..c211931bcc 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceRegionCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Texture/TextureSetDataSliceRegionCommand.cs @@ -1,6 +1,6 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL.Multithreading.Model; using Ryujinx.Graphics.GAL.Multithreading.Resources; +using System.Buffers; namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { @@ -8,12 +8,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Texture { public readonly CommandType CommandType => CommandType.TextureSetDataSliceRegion; private TableRef _texture; - private TableRef> _data; + private TableRef> _data; private int _layer; private int _level; private Rectangle _region; - public void Set(TableRef texture, TableRef> data, int layer, int level, Rectangle region) + public void Set(TableRef texture, TableRef> data, int layer, int level, Rectangle region) { _texture = texture; _data = data; diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs index fa71d20b37..80003b8447 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs @@ -1,6 +1,6 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL.Multithreading.Commands.Texture; using Ryujinx.Graphics.GAL.Multithreading.Model; +using System.Buffers; namespace Ryujinx.Graphics.GAL.Multithreading.Resources { @@ -111,21 +111,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources } /// - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { _renderer.New().Set(Ref(this), Ref(data)); _renderer.QueueCommand(); } /// - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { _renderer.New().Set(Ref(this), Ref(data), layer, level); _renderer.QueueCommand(); } /// - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { _renderer.New().Set(Ref(this), Ref(data), layer, level, region); _renderer.QueueCommand(); diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs index cdeae00409..f2bfd8eaa1 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Dma/DmaClass.cs @@ -1,10 +1,10 @@ using Ryujinx.Common; -using Ryujinx.Common.Memory; using Ryujinx.Graphics.Device; using Ryujinx.Graphics.Gpu.Engine.Threed; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Texture; using System; +using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -353,7 +353,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma if (target != null) { - MemoryOwner data; + IMemoryOwner data; if (srcLinear) { data = LayoutConverter.ConvertLinearStridedToLinear( diff --git a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs index ad6c1fecb2..5e66a3b543 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs @@ -1,4 +1,3 @@ -using System; using System.Collections; using System.Collections.Generic; @@ -47,11 +46,7 @@ namespace Ryujinx.Graphics.Gpu.Image { private const int MinCountForDeletion = 32; private const int MaxCapacity = 2048; - private const ulong MinTextureSizeCapacity = 512 * 1024 * 1024; - private const ulong MaxTextureSizeCapacity = 4UL * 1024 * 1024 * 1024; - private const ulong DefaultTextureSizeCapacity = 1UL * 1024 * 1024 * 1024; - private const float MemoryScaleFactor = 0.50f; - private ulong _maxCacheMemoryUsage = 0; + private const ulong MaxTextureSizeCapacity = 1024 * 1024 * 1024; // MB; private readonly LinkedList _textures; private ulong _totalSize; @@ -61,25 +56,6 @@ namespace Ryujinx.Graphics.Gpu.Image private readonly Dictionary _shortCacheLookup; - /// - /// Initializes the cache, setting the maximum texture capacity for the specified GPU context. - /// - /// - /// If the backend GPU has 0 memory capacity, the cache size defaults to `DefaultTextureSizeCapacity`. - /// - /// The GPU context that the cache belongs to - public void Initialize(GpuContext context) - { - var cacheMemory = (ulong)(context.Capabilities.MaximumGpuMemory * MemoryScaleFactor); - - _maxCacheMemoryUsage = Math.Clamp(cacheMemory, MinTextureSizeCapacity, MaxTextureSizeCapacity); - - if (context.Capabilities.MaximumGpuMemory == 0) - { - _maxCacheMemoryUsage = DefaultTextureSizeCapacity; - } - } - /// /// Creates a new instance of the automatic deletion cache. /// @@ -109,7 +85,7 @@ namespace Ryujinx.Graphics.Gpu.Image texture.CacheNode = _textures.AddLast(texture); if (_textures.Count > MaxCapacity || - (_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion)) + (_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion)) { RemoveLeastUsedTexture(); } @@ -134,7 +110,7 @@ namespace Ryujinx.Graphics.Gpu.Image _textures.AddLast(texture.CacheNode); } - if (_totalSize > _maxCacheMemoryUsage && _textures.Count >= MinCountForDeletion) + if (_totalSize > MaxTextureSizeCapacity && _textures.Count >= MinCountForDeletion) { RemoveLeastUsedTexture(); } diff --git a/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs b/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs index b007c15910..d6a3d975b8 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/Sampler.cs @@ -13,11 +13,6 @@ namespace Ryujinx.Graphics.Gpu.Image /// public bool IsDisposed { get; private set; } - /// - /// True if the sampler has sRGB conversion enabled, false otherwise. - /// - public bool IsSrgb { get; } - /// /// Host sampler object. /// @@ -35,8 +30,6 @@ namespace Ryujinx.Graphics.Gpu.Image /// The Maxwell sampler descriptor public Sampler(GpuContext context, SamplerDescriptor descriptor) { - IsSrgb = descriptor.UnpackSrgb(); - MinFilter minFilter = descriptor.UnpackMinFilter(); MagFilter magFilter = descriptor.UnpackMagFilter(); diff --git a/src/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs b/src/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs index 836a3260c6..e04c31dfaf 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/SamplerDescriptor.cs @@ -113,15 +113,6 @@ namespace Ryujinx.Graphics.Gpu.Image return (CompareOp)(((Word0 >> 10) & 7) + 1); } - /// - /// Unpacks the sampler sRGB format flag. - /// - /// True if the has sampler is sRGB conversion enabled, false otherwise - public readonly bool UnpackSrgb() - { - return (Word0 & (1 << 13)) != 0; - } - /// /// Unpacks and converts the maximum anisotropy value used for texture anisotropic filtering. /// diff --git a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs index 7ee2e5cf0b..3b6c407cc2 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -7,6 +7,7 @@ using Ryujinx.Graphics.Texture.Astc; using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; +using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -661,7 +662,7 @@ namespace Ryujinx.Graphics.Gpu.Image } } - MemoryOwner result = ConvertToHostCompatibleFormat(data); + IMemoryOwner result = ConvertToHostCompatibleFormat(data); if (ScaleFactor != 1f && AllowScaledSetData()) { @@ -684,7 +685,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// Uploads new texture data to the host GPU. /// /// New data - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { BlacklistScale(); @@ -703,7 +704,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// New data /// Target layer /// Target level - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { BlacklistScale(); @@ -721,7 +722,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// Target layer /// Target level /// Target sub-region of the texture to update - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { BlacklistScale(); @@ -739,7 +740,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// Mip level to convert /// True to convert a single slice /// Converted data - public MemoryOwner ConvertToHostCompatibleFormat(ReadOnlySpan data, int level = 0, bool single = false) + public IMemoryOwner ConvertToHostCompatibleFormat(ReadOnlySpan data, int level = 0, bool single = false) { int width = Info.Width; int height = Info.Height; @@ -754,7 +755,7 @@ namespace Ryujinx.Graphics.Gpu.Image int sliceDepth = single ? 1 : depth; - MemoryOwner linear; + IMemoryOwner linear; if (Info.IsLinear) { @@ -787,7 +788,7 @@ namespace Ryujinx.Graphics.Gpu.Image data); } - MemoryOwner result = linear; + IMemoryOwner result = linear; // Handle compressed cases not supported by the host: // - ASTC is usually not supported on desktop cards. @@ -831,19 +832,19 @@ namespace Ryujinx.Graphics.Gpu.Image case Format.Etc2RgbaUnorm: using (result) { - return ETC2Decoder.DecodeRgba(result.Span, width, height, sliceDepth, levels, layers); + return ETC2Decoder.DecodeRgba(result.Memory.Span, width, height, sliceDepth, levels, layers); } case Format.Etc2RgbPtaSrgb: case Format.Etc2RgbPtaUnorm: using (result) { - return ETC2Decoder.DecodePta(result.Span, width, height, sliceDepth, levels, layers); + return ETC2Decoder.DecodePta(result.Memory.Span, width, height, sliceDepth, levels, layers); } case Format.Etc2RgbSrgb: case Format.Etc2RgbUnorm: using (result) { - return ETC2Decoder.DecodeRgb(result.Span, width, height, sliceDepth, levels, layers); + return ETC2Decoder.DecodeRgb(result.Memory.Span, width, height, sliceDepth, levels, layers); } } } @@ -855,43 +856,43 @@ namespace Ryujinx.Graphics.Gpu.Image case Format.Bc1RgbaUnorm: using (result) { - return BCnDecoder.DecodeBC1(result.Span, width, height, sliceDepth, levels, layers); + return BCnDecoder.DecodeBC1(result.Memory.Span, width, height, sliceDepth, levels, layers); } case Format.Bc2Srgb: case Format.Bc2Unorm: using (result) { - return BCnDecoder.DecodeBC2(result.Span, width, height, sliceDepth, levels, layers); + return BCnDecoder.DecodeBC2(result.Memory.Span, width, height, sliceDepth, levels, layers); } case Format.Bc3Srgb: case Format.Bc3Unorm: using (result) { - return BCnDecoder.DecodeBC3(result.Span, width, height, sliceDepth, levels, layers); + return BCnDecoder.DecodeBC3(result.Memory.Span, width, height, sliceDepth, levels, layers); } case Format.Bc4Snorm: case Format.Bc4Unorm: using (result) { - return BCnDecoder.DecodeBC4(result.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc4Snorm); + return BCnDecoder.DecodeBC4(result.Memory.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc4Snorm); } case Format.Bc5Snorm: case Format.Bc5Unorm: using (result) { - return BCnDecoder.DecodeBC5(result.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc5Snorm); + return BCnDecoder.DecodeBC5(result.Memory.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc5Snorm); } case Format.Bc6HSfloat: case Format.Bc6HUfloat: using (result) { - return BCnDecoder.DecodeBC6(result.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc6HSfloat); + return BCnDecoder.DecodeBC6(result.Memory.Span, width, height, sliceDepth, levels, layers, Format == Format.Bc6HSfloat); } case Format.Bc7Srgb: case Format.Bc7Unorm: using (result) { - return BCnDecoder.DecodeBC7(result.Span, width, height, sliceDepth, levels, layers); + return BCnDecoder.DecodeBC7(result.Memory.Span, width, height, sliceDepth, levels, layers); } } } @@ -899,7 +900,7 @@ namespace Ryujinx.Graphics.Gpu.Image { using (result) { - var converted = PixelConverter.ConvertR4G4ToR4G4B4A4(result.Span, width); + var converted = PixelConverter.ConvertR4G4ToR4G4B4A4(result.Memory.Span, width); if (_context.Capabilities.SupportsR4G4B4A4Format) { @@ -909,7 +910,7 @@ namespace Ryujinx.Graphics.Gpu.Image { using (converted) { - return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(converted.Span, width); + return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(converted.Memory.Span, width); } } } @@ -920,7 +921,7 @@ namespace Ryujinx.Graphics.Gpu.Image { using (result) { - return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result.Span, width); + return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result.Memory.Span, width); } } } @@ -932,24 +933,24 @@ namespace Ryujinx.Graphics.Gpu.Image case Format.R5G6B5Unorm: using (result) { - return PixelConverter.ConvertR5G6B5ToR8G8B8A8(result.Span, width); + return PixelConverter.ConvertR5G6B5ToR8G8B8A8(result.Memory.Span, width); } case Format.B5G5R5A1Unorm: case Format.R5G5B5X1Unorm: case Format.R5G5B5A1Unorm: using (result) { - return PixelConverter.ConvertR5G5B5ToR8G8B8A8(result.Span, width, Format == Format.R5G5B5X1Unorm); + return PixelConverter.ConvertR5G5B5ToR8G8B8A8(result.Memory.Span, width, Format == Format.R5G5B5X1Unorm); } case Format.A1B5G5R5Unorm: using (result) { - return PixelConverter.ConvertA1B5G5R5ToR8G8B8A8(result.Span, width); + return PixelConverter.ConvertA1B5G5R5ToR8G8B8A8(result.Memory.Span, width); } case Format.R4G4B4A4Unorm: using (result) { - return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result.Span, width); + return PixelConverter.ConvertR4G4B4A4ToR8G8B8A8(result.Memory.Span, width); } } } diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index f96ddfb1bf..ad018f1597 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -187,9 +187,7 @@ namespace Ryujinx.Graphics.Gpu.Image { (TexturePool texturePool, SamplerPool samplerPool) = GetPools(); - Sampler sampler = samplerPool?.Get(samplerId); - - return (texturePool.Get(textureId, sampler?.IsSrgb ?? true), sampler); + return (texturePool.Get(textureId), samplerPool.Get(samplerId)); } /// @@ -510,12 +508,12 @@ namespace Ryujinx.Graphics.Gpu.Image state.TextureHandle = textureId; state.SamplerHandle = samplerId; - Sampler sampler = samplerPool?.Get(samplerId); - - ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, sampler?.IsSrgb ?? true, out Texture texture); + ref readonly TextureDescriptor descriptor = ref texturePool.GetForBinding(textureId, out Texture texture); specStateMatches &= specState.MatchesTexture(stage, index, descriptor); + Sampler sampler = samplerPool?.Get(samplerId); + ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target); ISampler hostSampler = sampler?.GetHostSampler(texture); diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index 1587e20189..5a3319b06a 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -68,14 +68,6 @@ namespace Ryujinx.Graphics.Gpu.Image _cache = new AutoDeleteCache(); } - /// - /// Initializes the cache, setting the maximum texture capacity for the specified GPU context. - /// - public void Initialize() - { - _cache.Initialize(_context); - } - /// /// Handles marking of textures written to a memory region being (partially) remapped. /// diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index 526fc0c246..06ca2c5997 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -1,4 +1,3 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Texture; @@ -6,6 +5,7 @@ using Ryujinx.Memory; using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; using System; +using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; @@ -445,7 +445,7 @@ namespace Ryujinx.Graphics.Gpu.Image ReadOnlySpan data = dataSpan[(offset - spanBase)..]; - MemoryOwner result = Storage.ConvertToHostCompatibleFormat(data, info.BaseLevel + level, true); + IMemoryOwner result = Storage.ConvertToHostCompatibleFormat(data, info.BaseLevel + level, true); Storage.SetData(result, info.BaseLayer + layer, info.BaseLevel + level); } diff --git a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs index be7cb0b893..5f43c1824e 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TexturePool.cs @@ -227,17 +227,6 @@ namespace Ryujinx.Graphics.Gpu.Image /// ID of the texture. This is effectively a zero-based index /// The texture with the given ID public override Texture Get(int id) - { - return Get(id, srgbSampler: true); - } - - /// - /// Gets the texture with the given ID. - /// - /// ID of the texture. This is effectively a zero-based index - /// Whether the texture is being accessed with a sampler that has sRGB conversion enabled - /// The texture with the given ID - public Texture Get(int id, bool srgbSampler) { if ((uint)id >= Items.Length) { @@ -251,7 +240,7 @@ namespace Ryujinx.Graphics.Gpu.Image SynchronizeMemory(); } - GetForBinding(id, srgbSampler, out Texture texture); + GetInternal(id, out Texture texture); return texture; } @@ -263,10 +252,9 @@ namespace Ryujinx.Graphics.Gpu.Image /// This method assumes that the pool has been manually synchronized before doing binding. /// /// ID of the texture. This is effectively a zero-based index - /// Whether the texture is being accessed with a sampler that has sRGB conversion enabled /// The texture with the given ID /// The texture descriptor with the given ID - public ref readonly TextureDescriptor GetForBinding(int id, bool srgbSampler, out Texture texture) + public ref readonly TextureDescriptor GetForBinding(int id, out Texture texture) { if ((uint)id >= Items.Length) { @@ -276,18 +264,6 @@ namespace Ryujinx.Graphics.Gpu.Image // When getting for binding, assume the pool has already been synchronized. - if (!srgbSampler) - { - // If the sampler does not have the sRGB bit enabled, then the texture can't use a sRGB format. - ref readonly TextureDescriptor tempDescriptor = ref GetDescriptorRef(id); - - if (tempDescriptor.UnpackSrgb() && FormatTable.TryGetTextureFormat(tempDescriptor.UnpackFormat(), isSrgb: false, out FormatInfo formatInfo)) - { - // Get a view of the texture with the right format. - return ref GetForBinding(id, formatInfo, out texture); - } - } - return ref GetInternal(id, out texture); } diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index d1065431d1..59a940a4f9 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; @@ -65,7 +64,6 @@ namespace Ryujinx.Graphics.Gpu.Memory MemoryUnmapped += Physical.BufferCache.MemoryUnmappedHandler; MemoryUnmapped += VirtualRangeCache.MemoryUnmappedHandler; MemoryUnmapped += CounterCache.MemoryUnmappedHandler; - Physical.TextureCache.Initialize(); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index c36fc0ada2..e1e696ca86 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 7353; + private const uint CodeGenVersion = 7320; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs index 1230c05805..98acb6f27d 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderSpecializationState.cs @@ -743,7 +743,7 @@ namespace Ryujinx.Graphics.Gpu.Shader constantBufferUsePerStageMask &= ~(1 << index); } - if (checkTextures && _allTextures.Length > 0) + if (checkTextures) { TexturePool pool = channel.TextureManager.GetTexturePool(poolState.TexturePoolGpuVa, poolState.TexturePoolMaximumId); diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs index 22f4c04cde..a8196541a1 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureBuffer.cs @@ -1,7 +1,7 @@ using OpenTK.Graphics.OpenGL; -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using System; +using System.Buffers; namespace Ryujinx.Graphics.OpenGL.Image { @@ -55,9 +55,9 @@ namespace Ryujinx.Graphics.OpenGL.Image } /// - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { - var dataSpan = data.Span; + var dataSpan = data.Memory.Span; Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]); @@ -65,13 +65,13 @@ namespace Ryujinx.Graphics.OpenGL.Image } /// - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { throw new NotSupportedException(); } /// - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { throw new NotSupportedException(); } diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index b0859c49e2..946eb755cc 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -1,8 +1,8 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Common; -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using System; +using System.Buffers; using System.Diagnostics; namespace Ryujinx.Graphics.OpenGL.Image @@ -448,13 +448,13 @@ namespace Ryujinx.Graphics.OpenGL.Image } } - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { using (data = EnsureDataFormat(data)) { unsafe { - var dataSpan = data.Span; + var dataSpan = data.Memory.Span; fixed (byte* ptr = dataSpan) { ReadFrom((IntPtr)ptr, dataSpan.Length); @@ -463,13 +463,13 @@ namespace Ryujinx.Graphics.OpenGL.Image } } - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { using (data = EnsureDataFormat(data)) { unsafe { - fixed (byte* ptr = data.Span) + fixed (byte* ptr = data.Memory.Span) { int width = Math.Max(Info.Width >> level, 1); int height = Math.Max(Info.Height >> level, 1); @@ -480,7 +480,7 @@ namespace Ryujinx.Graphics.OpenGL.Image } } - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { using (data = EnsureDataFormat(data)) { @@ -489,7 +489,7 @@ namespace Ryujinx.Graphics.OpenGL.Image unsafe { - fixed (byte* ptr = data.Span) + fixed (byte* ptr = data.Memory.Span) { ReadFrom2D( (IntPtr)ptr, @@ -522,13 +522,13 @@ namespace Ryujinx.Graphics.OpenGL.Image ReadFrom2D(data, layer, level, x, y, width, height, mipSize); } - private MemoryOwner EnsureDataFormat(MemoryOwner data) + private IMemoryOwner EnsureDataFormat(IMemoryOwner data) { if (Format == Format.S8UintD24Unorm) { using (data) { - return FormatConverter.ConvertS8D24ToD24S8(data.Span); + return FormatConverter.ConvertS8D24ToD24S8(data.Memory.Span); } } diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index 9fcdf1ad79..ba9cd45c67 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -202,8 +202,7 @@ namespace Ryujinx.Graphics.OpenGL shaderSubgroupSize: Constants.MaxSubgroupSize, storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment, textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment, - gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0, // Precision is 8 for these vendors on Vulkan. - maximumGpuMemory: 0); + gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan. } public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan data) diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs index 6ec90fa3c5..23180ff825 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/Utils.cs @@ -138,8 +138,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations // Ensure that conditions met for that branch are also met for the current one. // Prefer the latest sources for the phi node. - int undefCount = 0; - for (int i = phiNode.SourcesCount - 1; i >= 0; i--) { BasicBlock phiBlock = phiNode.GetBlock(i); @@ -161,26 +159,6 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations return match; } } - else if (phiSource.Type == OperandType.Undefined) - { - undefCount++; - } - } - - // If all sources but one are undefined, we can assume that the one - // that is not undefined is the right one. - - if (undefCount == phiNode.SourcesCount - 1) - { - for (int i = phiNode.SourcesCount - 1; i >= 0; i--) - { - Operand phiSource = phiNode.GetSource(i); - - if (phiSource.Type != OperandType.Undefined) - { - return phiSource; - } - } } } diff --git a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs index d1fbca0eb0..6a31ea2e79 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Shader.Translation if (stage == ShaderStage.Vertex) { - InitializeVertexOutputs(context); + InitializePositionOutput(context); } UInt128 usedAttributes = context.TranslatorContext.AttributeUsage.NextInputAttributesComponents; @@ -236,20 +236,12 @@ namespace Ryujinx.Graphics.Shader.Translation } } - private static void InitializeVertexOutputs(EmitterContext context) + private static void InitializePositionOutput(EmitterContext context) { for (int c = 0; c < 4; c++) { context.Store(StorageKind.Output, IoVariable.Position, null, Const(c), ConstF(c == 3 ? 1f : 0f)); } - - if (context.Program.ClipDistancesWritten != 0) - { - for (int i = 0; i < 8; i++) - { - context.Store(StorageKind.Output, IoVariable.ClipDistance, null, Const(i), ConstF(0f)); - } - } } private static void InitializeOutput(EmitterContext context, int location, bool perPatch) diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index addad83fd5..86fab760f1 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -636,9 +636,9 @@ namespace Ryujinx.Graphics.Vulkan var oldStencilTestEnable = _newState.StencilTestEnable; var oldDepthTestEnable = _newState.DepthTestEnable; var oldDepthWriteEnable = _newState.DepthWriteEnable; + var oldTopology = _newState.Topology; var oldViewports = DynamicState.Viewports; var oldViewportsCount = _newState.ViewportsCount; - var oldTopology = _topology; _newState.CullMode = CullModeFlags.None; _newState.StencilTestEnable = false; @@ -658,7 +658,7 @@ namespace Ryujinx.Graphics.Vulkan _newState.StencilTestEnable = oldStencilTestEnable; _newState.DepthTestEnable = oldDepthTestEnable; _newState.DepthWriteEnable = oldDepthWriteEnable; - SetPrimitiveTopology(oldTopology); + _newState.Topology = oldTopology; DynamicState.SetViewports(ref oldViewports, oldViewportsCount); diff --git a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index 073eee2ca9..bc1a509616 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -1,7 +1,7 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; +using System.Buffers; using System.Collections.Generic; using Format = Ryujinx.Graphics.GAL.Format; using VkFormat = Silk.NET.Vulkan.Format; @@ -84,20 +84,20 @@ namespace Ryujinx.Graphics.Vulkan } /// - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { - _gd.SetBufferData(_bufferHandle, _offset, data.Span); + _gd.SetBufferData(_bufferHandle, _offset, data.Memory.Span); data.Dispose(); } /// - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { throw new NotSupportedException(); } /// - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { throw new NotSupportedException(); } diff --git a/src/Ryujinx.Graphics.Vulkan/TextureView.cs b/src/Ryujinx.Graphics.Vulkan/TextureView.cs index b7b936809d..9b3f466627 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -1,7 +1,7 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; +using System.Buffers; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -746,23 +746,23 @@ namespace Ryujinx.Graphics.Vulkan } /// - public void SetData(MemoryOwner data) + public void SetData(IMemoryOwner data) { - SetData(data.Span, 0, 0, Info.GetLayers(), Info.Levels, singleSlice: false); + SetData(data.Memory.Span, 0, 0, Info.GetLayers(), Info.Levels, singleSlice: false); data.Dispose(); } /// - public void SetData(MemoryOwner data, int layer, int level) + public void SetData(IMemoryOwner data, int layer, int level) { - SetData(data.Span, layer, level, 1, 1, singleSlice: true); + SetData(data.Memory.Span, layer, level, 1, 1, singleSlice: true); data.Dispose(); } /// - public void SetData(MemoryOwner data, int layer, int level, Rectangle region) + public void SetData(IMemoryOwner data, int layer, int level, Rectangle region) { - SetData(data.Span, layer, level, 1, 1, singleSlice: true, region); + SetData(data.Memory.Span, layer, level, 1, 1, singleSlice: true, region); data.Dispose(); } diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 0faaec82a4..33e41ab489 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -781,26 +781,7 @@ namespace Ryujinx.Graphics.Vulkan shaderSubgroupSize: (int)Capabilities.SubgroupSize, storageBufferOffsetAlignment: (int)limits.MinStorageBufferOffsetAlignment, textureBufferOffsetAlignment: (int)limits.MinTexelBufferOffsetAlignment, - gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0, - maximumGpuMemory: GetTotalGPUMemory()); - } - - private ulong GetTotalGPUMemory() - { - ulong totalMemory = 0; - - Api.GetPhysicalDeviceMemoryProperties(_physicalDevice.PhysicalDevice, out PhysicalDeviceMemoryProperties memoryProperties); - - for (int i = 0; i < memoryProperties.MemoryHeapCount; i++) - { - var heap = memoryProperties.MemoryHeaps[i]; - if ((heap.Flags & MemoryHeapFlags.DeviceLocalBit) == MemoryHeapFlags.DeviceLocalBit) - { - totalMemory += heap.Size; - } - } - - return totalMemory; + gatherBiasPrecision: IsIntelWindows || IsAmdWindows ? (int)Capabilities.SubTexelPrecisionBits : 0); } public HardwareInfo GetHardwareInfo() @@ -884,7 +865,6 @@ namespace Ryujinx.Graphics.Vulkan private void PrintGpuInformation() { Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})"); - Logger.Notice.Print(LogClass.Gpu, $"GPU Memory: {GetTotalGPUMemory() / (1024 * 1024)} MiB"); } public void Initialize(GraphicsDebugLevel logLevel) diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs index 1df280dce4..2ca0e1aac2 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/Parcel.cs @@ -14,7 +14,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { private readonly MemoryOwner _rawDataOwner; - private Span Raw => _rawDataOwner.Span; + private Span Raw => _rawDataOwner.Memory.Span; private ref ParcelHeader Header => ref MemoryMarshal.Cast(Raw)[0]; diff --git a/src/Ryujinx.Horizon/Sdk/Audio/AudioResult.cs b/src/Ryujinx.Horizon/Sdk/Audio/AudioResult.cs index 5914a747cb..c18bfee9fc 100644 --- a/src/Ryujinx.Horizon/Sdk/Audio/AudioResult.cs +++ b/src/Ryujinx.Horizon/Sdk/Audio/AudioResult.cs @@ -8,6 +8,5 @@ namespace Ryujinx.Horizon.Sdk.Audio public static Result DeviceNotFound => new(ModuleId, 1); public static Result UnsupportedRevision => new(ModuleId, 2); - public static Result NotImplemented => new(ModuleId, 513); } } diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs index 2d3aa7ba92..f67ea72988 100644 --- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs +++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs @@ -233,48 +233,6 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail return Result.Success; } - [CmifCommand(15)] // 17.0.0+ - public Result AcquireAudioOutputDeviceNotification([CopyHandle] out int eventHandle, ulong deviceId) - { - eventHandle = 0; - - return AudioResult.NotImplemented; - } - - [CmifCommand(16)] // 17.0.0+ - public Result ReleaseAudioOutputDeviceNotification(ulong deviceId) - { - return AudioResult.NotImplemented; - } - - [CmifCommand(17)] // 17.0.0+ - public Result AcquireAudioInputDeviceNotification([CopyHandle] out int eventHandle, ulong deviceId) - { - eventHandle = 0; - - return AudioResult.NotImplemented; - } - - [CmifCommand(18)] // 17.0.0+ - public Result ReleaseAudioInputDeviceNotification(ulong deviceId) - { - return AudioResult.NotImplemented; - } - - [CmifCommand(19)] // 18.0.0+ - public Result SetAudioDeviceOutputVolumeAutoTuneEnabled(bool enabled) - { - return AudioResult.NotImplemented; - } - - [CmifCommand(20)] // 18.0.0+ - public Result IsAudioDeviceOutputVolumeAutoTuneEnabled(out bool enabled) - { - enabled = false; - - return AudioResult.NotImplemented; - } - protected virtual void Dispose(bool disposing) { if (disposing) diff --git a/src/Ryujinx.Memory/WritableRegion.cs b/src/Ryujinx.Memory/WritableRegion.cs index 54facb5085..2c21ef4e80 100644 --- a/src/Ryujinx.Memory/WritableRegion.cs +++ b/src/Ryujinx.Memory/WritableRegion.cs @@ -1,5 +1,5 @@ -using Ryujinx.Common.Memory; using System; +using System.Buffers; namespace Ryujinx.Memory { @@ -7,7 +7,7 @@ namespace Ryujinx.Memory { private readonly IWritableBlock _block; private readonly ulong _va; - private readonly MemoryOwner _memoryOwner; + private readonly IMemoryOwner _memoryOwner; private readonly bool _tracked; private bool NeedsWriteback => _block != null; @@ -22,7 +22,7 @@ namespace Ryujinx.Memory Memory = memory; } - public WritableRegion(IWritableBlock block, ulong va, MemoryOwner memoryOwner, bool tracked = false) + public WritableRegion(IWritableBlock block, ulong va, IMemoryOwner memoryOwner, bool tracked = false) : this(block, va, memoryOwner.Memory, tracked) { _memoryOwner = memoryOwner; diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 9827156d03..ed6d941908 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -53,7 +53,6 @@ namespace Ryujinx.SDL2.Common return; } - SDL_SetHint(SDL_HINT_APP_NAME, "Ryujinx"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs index 0b0ed7a542..3e48a5b4ec 100644 --- a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs +++ b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs @@ -55,7 +55,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -84,7 +83,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -113,7 +111,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -142,7 +139,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.75f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -171,7 +167,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -200,7 +195,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -229,7 +223,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -258,7 +251,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -287,7 +279,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -316,7 +307,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(4, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -345,7 +335,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); @@ -374,36 +363,6 @@ namespace Ryujinx.Tests.Audio.Renderer.Server Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing()); Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported()); Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported()); - - Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); - Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion()); - Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat()); - } - - [Test] - public void TestRevision13() - { - BehaviourContext behaviourContext = new(); - - behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision13); - - Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed()); - Assert.IsTrue(behaviourContext.IsSplitterSupported()); - Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported()); - Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported()); - Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported()); - Assert.IsTrue(behaviourContext.IsSplitterBugFixed()); - Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported()); - Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported()); - Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed()); - Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported()); - Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported()); - Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported()); - Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing()); - Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported()); - Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled()); - Assert.IsTrue(behaviourContext.IsSplitterPrevVolumeResetSupported()); Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit()); Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());