Compare commits

..

5 Commits

Author SHA1 Message Date
merry
6dfb6ccf8c PreAllocator: Check if instruction supports a Vex prefix in IsVexSameOperandDestSrc1 (#3587) 2022-08-14 17:35:08 -03:00
gdkchan
e87e8b012c Fix texture bindings using wrong sampler pool in some cases (#3583) 2022-08-14 14:00:30 -03:00
gdkchan
e8f1ca8427 OpenGL: Limit vertex buffer range for non-indexed draws (#3542)
* Limit vertex buffer range for non-indexed draws

* Fix typo
2022-08-11 20:21:56 -03:00
gdkchan
ad47bd2d4e Fix blend with RGBX color formats (#3553) 2022-08-11 18:23:25 -03:00
gdkchan
a5ff0024fb Rename ToSpan to AsSpan (#3556) 2022-08-11 18:07:37 -03:00
54 changed files with 534 additions and 392 deletions

View File

@@ -4,6 +4,11 @@ namespace ARMeilleure.CodeGen.X86
{ {
partial class Assembler partial class Assembler
{ {
public static bool SupportsVexPrefix(X86Instruction inst)
{
return _instTable[(int)inst].Flags.HasFlag(InstructionFlags.Vex);
}
private const int BadOp = 0; private const int BadOp = 0;
[Flags] [Flags]

View File

@@ -1297,11 +1297,15 @@ namespace ARMeilleure.CodeGen.X86
{ {
if (IsIntrinsic(operation.Instruction)) if (IsIntrinsic(operation.Instruction))
{ {
IntrinsicInfo info = IntrinsicTable.GetInfo(operation.Intrinsic);
bool hasVex = HardwareCapabilities.SupportsVexEncoding && Assembler.SupportsVexPrefix(info.Inst);
bool isUnary = operation.SourcesCount < 2; bool isUnary = operation.SourcesCount < 2;
bool hasVecDest = operation.Destination != default && operation.Destination.Type == OperandType.V128; bool hasVecDest = operation.Destination != default && operation.Destination.Type == OperandType.V128;
return !HardwareCapabilities.SupportsVexEncoding && !isUnary && hasVecDest; return !hasVex && !isUnary && hasVecDest;
} }
return false; return false;

View File

@@ -76,7 +76,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
if (!info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion)) if (!info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion))
{ {
voiceState.Pitch.ToSpan().Slice(0, pitchMaxLength).CopyTo(tempBuffer); voiceState.Pitch.AsSpan().Slice(0, pitchMaxLength).CopyTo(tempBuffer);
tempBufferIndex += pitchMaxLength; tempBufferIndex += pitchMaxLength;
} }
@@ -239,7 +239,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
ResamplerHelper.Resample(outputBuffer, tempBuffer, sampleRateRatio, ref fraction, sampleCountToProcess, info.SrcQuality, y != sourceSampleCountToProcess || info.Pitch != 1.0f); ResamplerHelper.Resample(outputBuffer, tempBuffer, sampleRateRatio, ref fraction, sampleCountToProcess, info.SrcQuality, y != sourceSampleCountToProcess || info.Pitch != 1.0f);
tempBuffer.Slice(sampleCountToDecode, pitchMaxLength).CopyTo(voiceState.Pitch.ToSpan()); tempBuffer.Slice(sampleCountToDecode, pitchMaxLength).CopyTo(voiceState.Pitch.AsSpan());
} }
i += sampleCountToProcess; i += sampleCountToProcess;

View File

@@ -24,8 +24,8 @@ namespace Ryujinx.Audio.Renderer.Parameter.Effect
/// </summary> /// </summary>
public void Reset() public void Reset()
{ {
InputMax.ToSpan().Fill(0.0f); InputMax.AsSpan().Fill(0.0f);
CompressionGainMin.ToSpan().Fill(1.0f); CompressionGainMin.AsSpan().Fill(1.0f);
} }
} }
} }

View File

@@ -141,7 +141,7 @@ namespace Ryujinx.Audio.Renderer.Server
Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state).Slice(VoiceUpdateState.BiquadStateOffset, VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount); Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state).Slice(VoiceUpdateState.BiquadStateOffset, VoiceUpdateState.BiquadStateSize * Constants.VoiceBiquadFilterCount);
Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory); Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory);
_commandBuffer.GenerateGroupedBiquadFilter(baseIndex, voiceState.BiquadFilters.ToSpan(), stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId); _commandBuffer.GenerateGroupedBiquadFilter(baseIndex, voiceState.BiquadFilters.AsSpan(), stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
} }
else else
{ {
@@ -337,8 +337,8 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId); GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
} }
GenerateVoiceMix(channelResource.Mix.ToSpan(), GenerateVoiceMix(channelResource.Mix.AsSpan(),
channelResource.PreviousMix.ToSpan(), channelResource.PreviousMix.AsSpan(),
dspStateMemory, dspStateMemory,
mix.BufferOffset, mix.BufferOffset,
mix.BufferCount, mix.BufferCount,
@@ -505,8 +505,8 @@ namespace Ryujinx.Audio.Renderer.Server
BiquadFilterParameter parameter = new BiquadFilterParameter(); BiquadFilterParameter parameter = new BiquadFilterParameter();
parameter.Enable = true; parameter.Enable = true;
effect.Parameter.Denominator.ToSpan().CopyTo(parameter.Denominator.ToSpan()); effect.Parameter.Denominator.AsSpan().CopyTo(parameter.Denominator.AsSpan());
effect.Parameter.Numerator.ToSpan().CopyTo(parameter.Numerator.ToSpan()); effect.Parameter.Numerator.AsSpan().CopyTo(parameter.Numerator.AsSpan());
for (int i = 0; i < effect.Parameter.ChannelCount; i++) for (int i = 0; i < effect.Parameter.ChannelCount; i++)
{ {
@@ -923,8 +923,8 @@ namespace Ryujinx.Audio.Renderer.Server
if (useCustomDownMixingCommand) if (useCustomDownMixingCommand)
{ {
_commandBuffer.GenerateDownMixSurroundToStereo(finalMix.BufferOffset, _commandBuffer.GenerateDownMixSurroundToStereo(finalMix.BufferOffset,
sink.Parameter.Input.ToSpan(), sink.Parameter.Input.AsSpan(),
sink.Parameter.Input.ToSpan(), sink.Parameter.Input.AsSpan(),
sink.DownMixCoefficients, sink.DownMixCoefficients,
Constants.InvalidNodeId); Constants.InvalidNodeId);
} }
@@ -932,8 +932,8 @@ namespace Ryujinx.Audio.Renderer.Server
else if (_rendererContext.ChannelCount == 2 && sink.Parameter.InputCount == 6) else if (_rendererContext.ChannelCount == 2 && sink.Parameter.InputCount == 6)
{ {
_commandBuffer.GenerateDownMixSurroundToStereo(finalMix.BufferOffset, _commandBuffer.GenerateDownMixSurroundToStereo(finalMix.BufferOffset,
sink.Parameter.Input.ToSpan(), sink.Parameter.Input.AsSpan(),
sink.Parameter.Input.ToSpan(), sink.Parameter.Input.AsSpan(),
Constants.DefaultSurroundToStereoCoefficients, Constants.DefaultSurroundToStereoCoefficients,
Constants.InvalidNodeId); Constants.InvalidNodeId);
} }
@@ -945,7 +945,7 @@ namespace Ryujinx.Audio.Renderer.Server
_commandBuffer.GenerateUpsample(finalMix.BufferOffset, _commandBuffer.GenerateUpsample(finalMix.BufferOffset,
sink.UpsamplerState, sink.UpsamplerState,
sink.Parameter.InputCount, sink.Parameter.InputCount,
sink.Parameter.Input.ToSpan(), sink.Parameter.Input.AsSpan(),
commandList.BufferCount, commandList.BufferCount,
commandList.SampleCount, commandList.SampleCount,
commandList.SampleRate, commandList.SampleRate,

View File

@@ -63,10 +63,10 @@ namespace Ryujinx.Audio.Renderer.Server.Sink
else else
{ {
Parameter.DownMixParameterEnabled = inputDeviceParameter.DownMixParameterEnabled; Parameter.DownMixParameterEnabled = inputDeviceParameter.DownMixParameterEnabled;
inputDeviceParameter.DownMixParameter.ToSpan().CopyTo(Parameter.DownMixParameter.ToSpan()); inputDeviceParameter.DownMixParameter.AsSpan().CopyTo(Parameter.DownMixParameter.AsSpan());
} }
Parameter.DownMixParameter.ToSpan().CopyTo(DownMixCoefficients.AsSpan()); Parameter.DownMixParameter.AsSpan().CopyTo(DownMixCoefficients.AsSpan());
errorInfo = new BehaviourParameter.ErrorInfo(); errorInfo = new BehaviourParameter.ErrorInfo();
outStatus = new SinkOutStatus(); outStatus = new SinkOutStatus();

View File

@@ -119,7 +119,7 @@ namespace Ryujinx.Audio.Renderer.Server
ref VoiceChannelResource resource = ref context.GetChannelResource(i); ref VoiceChannelResource resource = ref context.GetChannelResource(i);
resource.Id = parameter.Id; resource.Id = parameter.Id;
parameter.Mix.ToSpan().CopyTo(resource.Mix.ToSpan()); parameter.Mix.AsSpan().CopyTo(resource.Mix.AsSpan());
resource.IsUsed = parameter.IsUsed; resource.IsUsed = parameter.IsUsed;
} }
@@ -587,7 +587,7 @@ namespace Ryujinx.Audio.Renderer.Server
{ {
ref BehaviourErrorInfoOutStatus outStatus = ref SpanIOHelper.GetWriteRef<BehaviourErrorInfoOutStatus>(ref _output)[0]; ref BehaviourErrorInfoOutStatus outStatus = ref SpanIOHelper.GetWriteRef<BehaviourErrorInfoOutStatus>(ref _output)[0];
_behaviourContext.CopyErrorInfo(outStatus.ErrorInfos.ToSpan(), out outStatus.ErrorInfosCount); _behaviourContext.CopyErrorInfo(outStatus.ErrorInfos.AsSpan(), out outStatus.ErrorInfosCount);
OutputHeader.BehaviourSize = (uint)Unsafe.SizeOf<BehaviourErrorInfoOutStatus>(); OutputHeader.BehaviourSize = (uint)Unsafe.SizeOf<BehaviourErrorInfoOutStatus>();
OutputHeader.TotalSize += OutputHeader.BehaviourSize; OutputHeader.TotalSize += OutputHeader.BehaviourSize;

View File

@@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
public void UpdateState() public void UpdateState()
{ {
Mix.ToSpan().CopyTo(PreviousMix.ToSpan()); Mix.AsSpan().CopyTo(PreviousMix.AsSpan());
} }
} }
} }

View File

@@ -202,7 +202,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
Pitch = 0.0f; Pitch = 0.0f;
Volume = 0.0f; Volume = 0.0f;
PreviousVolume = 0.0f; PreviousVolume = 0.0f;
BiquadFilters.ToSpan().Fill(new BiquadFilterParameter()); BiquadFilters.AsSpan().Fill(new BiquadFilterParameter());
WaveBuffersCount = 0; WaveBuffersCount = 0;
WaveBuffersIndex = 0; WaveBuffersIndex = 0;
MixId = Constants.UnusedMixId; MixId = Constants.UnusedMixId;
@@ -288,7 +288,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
ChannelsCount = parameter.ChannelCount; ChannelsCount = parameter.ChannelCount;
Pitch = parameter.Pitch; Pitch = parameter.Pitch;
Volume = parameter.Volume; Volume = parameter.Volume;
parameter.BiquadFilters.ToSpan().CopyTo(BiquadFilters.ToSpan()); parameter.BiquadFilters.AsSpan().CopyTo(BiquadFilters.AsSpan());
WaveBuffersCount = parameter.WaveBuffersCount; WaveBuffersCount = parameter.WaveBuffersCount;
WaveBuffersIndex = parameter.WaveBuffersIndex; WaveBuffersIndex = parameter.WaveBuffersIndex;
@@ -308,7 +308,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
SplitterId = Constants.UnusedSplitterId; SplitterId = Constants.UnusedSplitterId;
} }
parameter.ChannelResourceIds.ToSpan().CopyTo(ChannelResourceIds.ToSpan()); parameter.ChannelResourceIds.AsSpan().CopyTo(ChannelResourceIds.AsSpan());
DecodingBehaviour behaviour = DecodingBehaviour.Default; DecodingBehaviour behaviour = DecodingBehaviour.Default;
@@ -638,7 +638,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
voiceUpdateState.Offset = 0; voiceUpdateState.Offset = 0;
voiceUpdateState.PlayedSampleCount = 0; voiceUpdateState.PlayedSampleCount = 0;
voiceUpdateState.Pitch.ToSpan().Fill(0); voiceUpdateState.Pitch.AsSpan().Fill(0);
voiceUpdateState.Fraction = 0; voiceUpdateState.Fraction = 0;
voiceUpdateState.LoopContext = new Dsp.State.AdpcmLoopContext(); voiceUpdateState.LoopContext = new Dsp.State.AdpcmLoopContext();
} }
@@ -650,7 +650,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
case Types.PlayState.Stopped: case Types.PlayState.Stopped:
case Types.PlayState.Paused: case Types.PlayState.Paused:
foreach (ref WaveBuffer wavebuffer in WaveBuffers.ToSpan()) foreach (ref WaveBuffer wavebuffer in WaveBuffers.AsSpan())
{ {
wavebuffer.BufferAddressInfo.GetReference(true); wavebuffer.BufferAddressInfo.GetReference(true);
wavebuffer.ContextAddressInfo.GetReference(true); wavebuffer.ContextAddressInfo.GetReference(true);

View File

@@ -87,7 +87,7 @@ namespace Ryujinx.Common.Memory
/// Gets a span from the array. /// Gets a span from the array.
/// </summary> /// </summary>
/// <returns>Span of the array</returns> /// <returns>Span of the array</returns>
public Span<T> ToSpan() => Length == 0 ? Span<T>.Empty : MemoryMarshal.CreateSpan(ref this[0], Length); public Span<T> AsSpan() => Length == 0 ? Span<T>.Empty : MemoryMarshal.CreateSpan(ref this[0], Length);
/// <summary> /// <summary>
/// Gets the array base pointer. /// Gets the array base pointer.

View File

@@ -128,7 +128,7 @@ namespace Ryujinx.Common.Memory.PartialUnmaps
const uint ExitCodeStillActive = 259; const uint ExitCodeStillActive = 259;
const int ThreadQueryInformation = 0x40; const int ThreadQueryInformation = 0x40;
Span<int> ids = LocalCounts.ThreadIds.ToSpan(); Span<int> ids = LocalCounts.ThreadIds.AsSpan();
for (int i = 0; i < ids.Length; i++) for (int i = 0; i < ids.Length; i++)
{ {

View File

@@ -7,8 +7,8 @@ namespace Ryujinx.Common.Memory
{ {
T _e0; T _e0;
public int Length => 1; public int Length => 1;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 1); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 1);
} }
public struct Array2<T> : IArray<T> where T : unmanaged public struct Array2<T> : IArray<T> where T : unmanaged
{ {
@@ -17,8 +17,8 @@ namespace Ryujinx.Common.Memory
Array1<T> _other; Array1<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 2; public int Length => 2;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 2); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 2);
} }
public struct Array3<T> : IArray<T> where T : unmanaged public struct Array3<T> : IArray<T> where T : unmanaged
{ {
@@ -27,8 +27,8 @@ namespace Ryujinx.Common.Memory
Array2<T> _other; Array2<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 3; public int Length => 3;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 3); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 3);
} }
public struct Array4<T> : IArray<T> where T : unmanaged public struct Array4<T> : IArray<T> where T : unmanaged
{ {
@@ -37,8 +37,8 @@ namespace Ryujinx.Common.Memory
Array3<T> _other; Array3<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 4; public int Length => 4;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 4); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 4);
} }
public struct Array5<T> : IArray<T> where T : unmanaged public struct Array5<T> : IArray<T> where T : unmanaged
{ {
@@ -47,8 +47,8 @@ namespace Ryujinx.Common.Memory
Array4<T> _other; Array4<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 5; public int Length => 5;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 5); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 5);
} }
public struct Array6<T> : IArray<T> where T : unmanaged public struct Array6<T> : IArray<T> where T : unmanaged
{ {
@@ -57,8 +57,8 @@ namespace Ryujinx.Common.Memory
Array5<T> _other; Array5<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 6; public int Length => 6;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 6); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 6);
} }
public struct Array7<T> : IArray<T> where T : unmanaged public struct Array7<T> : IArray<T> where T : unmanaged
{ {
@@ -67,8 +67,8 @@ namespace Ryujinx.Common.Memory
Array6<T> _other; Array6<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 7; public int Length => 7;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 7); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 7);
} }
public struct Array8<T> : IArray<T> where T : unmanaged public struct Array8<T> : IArray<T> where T : unmanaged
{ {
@@ -77,8 +77,8 @@ namespace Ryujinx.Common.Memory
Array7<T> _other; Array7<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 8; public int Length => 8;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 8); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 8);
} }
public struct Array9<T> : IArray<T> where T : unmanaged public struct Array9<T> : IArray<T> where T : unmanaged
{ {
@@ -87,8 +87,8 @@ namespace Ryujinx.Common.Memory
Array8<T> _other; Array8<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 9; public int Length => 9;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 9); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 9);
} }
public struct Array10<T> : IArray<T> where T : unmanaged public struct Array10<T> : IArray<T> where T : unmanaged
{ {
@@ -97,8 +97,8 @@ namespace Ryujinx.Common.Memory
Array9<T> _other; Array9<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 10; public int Length => 10;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 10); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 10);
} }
public struct Array11<T> : IArray<T> where T : unmanaged public struct Array11<T> : IArray<T> where T : unmanaged
{ {
@@ -107,8 +107,8 @@ namespace Ryujinx.Common.Memory
Array10<T> _other; Array10<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 11; public int Length => 11;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 11); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 11);
} }
public struct Array12<T> : IArray<T> where T : unmanaged public struct Array12<T> : IArray<T> where T : unmanaged
{ {
@@ -117,8 +117,8 @@ namespace Ryujinx.Common.Memory
Array11<T> _other; Array11<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 12; public int Length => 12;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 12); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 12);
} }
public struct Array13<T> : IArray<T> where T : unmanaged public struct Array13<T> : IArray<T> where T : unmanaged
{ {
@@ -127,8 +127,8 @@ namespace Ryujinx.Common.Memory
Array12<T> _other; Array12<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 13; public int Length => 13;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 13); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 13);
} }
public struct Array14<T> : IArray<T> where T : unmanaged public struct Array14<T> : IArray<T> where T : unmanaged
{ {
@@ -137,8 +137,8 @@ namespace Ryujinx.Common.Memory
Array13<T> _other; Array13<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 14; public int Length => 14;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 14); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 14);
} }
public struct Array15<T> : IArray<T> where T : unmanaged public struct Array15<T> : IArray<T> where T : unmanaged
{ {
@@ -147,8 +147,8 @@ namespace Ryujinx.Common.Memory
Array14<T> _other; Array14<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 15; public int Length => 15;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 15); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 15);
} }
public struct Array16<T> : IArray<T> where T : unmanaged public struct Array16<T> : IArray<T> where T : unmanaged
{ {
@@ -157,8 +157,8 @@ namespace Ryujinx.Common.Memory
Array15<T> _other; Array15<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 16; public int Length => 16;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 16); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 16);
} }
public struct Array17<T> : IArray<T> where T : unmanaged public struct Array17<T> : IArray<T> where T : unmanaged
{ {
@@ -167,8 +167,8 @@ namespace Ryujinx.Common.Memory
Array16<T> _other; Array16<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 17; public int Length => 17;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 17); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 17);
} }
public struct Array18<T> : IArray<T> where T : unmanaged public struct Array18<T> : IArray<T> where T : unmanaged
{ {
@@ -177,8 +177,8 @@ namespace Ryujinx.Common.Memory
Array17<T> _other; Array17<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 18; public int Length => 18;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 18); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 18);
} }
public struct Array19<T> : IArray<T> where T : unmanaged public struct Array19<T> : IArray<T> where T : unmanaged
{ {
@@ -187,8 +187,8 @@ namespace Ryujinx.Common.Memory
Array18<T> _other; Array18<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 19; public int Length => 19;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 19); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 19);
} }
public struct Array20<T> : IArray<T> where T : unmanaged public struct Array20<T> : IArray<T> where T : unmanaged
{ {
@@ -197,8 +197,8 @@ namespace Ryujinx.Common.Memory
Array19<T> _other; Array19<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 20; public int Length => 20;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 20); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 20);
} }
public struct Array21<T> : IArray<T> where T : unmanaged public struct Array21<T> : IArray<T> where T : unmanaged
{ {
@@ -207,8 +207,8 @@ namespace Ryujinx.Common.Memory
Array20<T> _other; Array20<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 21; public int Length => 21;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 21); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 21);
} }
public struct Array22<T> : IArray<T> where T : unmanaged public struct Array22<T> : IArray<T> where T : unmanaged
{ {
@@ -217,8 +217,8 @@ namespace Ryujinx.Common.Memory
Array21<T> _other; Array21<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 22; public int Length => 22;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 22); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 22);
} }
public struct Array23<T> : IArray<T> where T : unmanaged public struct Array23<T> : IArray<T> where T : unmanaged
{ {
@@ -227,8 +227,8 @@ namespace Ryujinx.Common.Memory
Array22<T> _other; Array22<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 23; public int Length => 23;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 23); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 23);
} }
public struct Array24<T> : IArray<T> where T : unmanaged public struct Array24<T> : IArray<T> where T : unmanaged
{ {
@@ -237,8 +237,8 @@ namespace Ryujinx.Common.Memory
Array23<T> _other; Array23<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 24; public int Length => 24;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 24); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 24);
} }
public struct Array25<T> : IArray<T> where T : unmanaged public struct Array25<T> : IArray<T> where T : unmanaged
{ {
@@ -247,8 +247,8 @@ namespace Ryujinx.Common.Memory
Array24<T> _other; Array24<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 25; public int Length => 25;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 25); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 25);
} }
public struct Array26<T> : IArray<T> where T : unmanaged public struct Array26<T> : IArray<T> where T : unmanaged
{ {
@@ -257,8 +257,8 @@ namespace Ryujinx.Common.Memory
Array25<T> _other; Array25<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 26; public int Length => 26;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 26); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 26);
} }
public struct Array27<T> : IArray<T> where T : unmanaged public struct Array27<T> : IArray<T> where T : unmanaged
{ {
@@ -267,8 +267,8 @@ namespace Ryujinx.Common.Memory
Array26<T> _other; Array26<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 27; public int Length => 27;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 27); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 27);
} }
public struct Array28<T> : IArray<T> where T : unmanaged public struct Array28<T> : IArray<T> where T : unmanaged
{ {
@@ -277,8 +277,8 @@ namespace Ryujinx.Common.Memory
Array27<T> _other; Array27<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 28; public int Length => 28;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 28); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 28);
} }
public struct Array29<T> : IArray<T> where T : unmanaged public struct Array29<T> : IArray<T> where T : unmanaged
{ {
@@ -287,8 +287,8 @@ namespace Ryujinx.Common.Memory
Array28<T> _other; Array28<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 29; public int Length => 29;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 29); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 29);
} }
public struct Array30<T> : IArray<T> where T : unmanaged public struct Array30<T> : IArray<T> where T : unmanaged
{ {
@@ -297,8 +297,8 @@ namespace Ryujinx.Common.Memory
Array29<T> _other; Array29<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 30; public int Length => 30;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 30); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 30);
} }
public struct Array31<T> : IArray<T> where T : unmanaged public struct Array31<T> : IArray<T> where T : unmanaged
{ {
@@ -307,8 +307,8 @@ namespace Ryujinx.Common.Memory
Array30<T> _other; Array30<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 31; public int Length => 31;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 31); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 31);
} }
public struct Array32<T> : IArray<T> where T : unmanaged public struct Array32<T> : IArray<T> where T : unmanaged
{ {
@@ -317,8 +317,8 @@ namespace Ryujinx.Common.Memory
Array31<T> _other; Array31<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 32; public int Length => 32;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 32); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 32);
} }
public struct Array33<T> : IArray<T> where T : unmanaged public struct Array33<T> : IArray<T> where T : unmanaged
{ {
@@ -327,8 +327,8 @@ namespace Ryujinx.Common.Memory
Array32<T> _other; Array32<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 33; public int Length => 33;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 33); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 33);
} }
public struct Array34<T> : IArray<T> where T : unmanaged public struct Array34<T> : IArray<T> where T : unmanaged
{ {
@@ -337,8 +337,8 @@ namespace Ryujinx.Common.Memory
Array33<T> _other; Array33<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 34; public int Length => 34;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 34); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 34);
} }
public struct Array35<T> : IArray<T> where T : unmanaged public struct Array35<T> : IArray<T> where T : unmanaged
{ {
@@ -347,8 +347,8 @@ namespace Ryujinx.Common.Memory
Array34<T> _other; Array34<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 35; public int Length => 35;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 35); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 35);
} }
public struct Array36<T> : IArray<T> where T : unmanaged public struct Array36<T> : IArray<T> where T : unmanaged
{ {
@@ -357,8 +357,8 @@ namespace Ryujinx.Common.Memory
Array35<T> _other; Array35<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 36; public int Length => 36;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 36); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 36);
} }
public struct Array37<T> : IArray<T> where T : unmanaged public struct Array37<T> : IArray<T> where T : unmanaged
{ {
@@ -367,8 +367,8 @@ namespace Ryujinx.Common.Memory
Array36<T> _other; Array36<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 37; public int Length => 37;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 37); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 37);
} }
public struct Array38<T> : IArray<T> where T : unmanaged public struct Array38<T> : IArray<T> where T : unmanaged
{ {
@@ -377,8 +377,8 @@ namespace Ryujinx.Common.Memory
Array37<T> _other; Array37<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 38; public int Length => 38;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 38); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 38);
} }
public struct Array39<T> : IArray<T> where T : unmanaged public struct Array39<T> : IArray<T> where T : unmanaged
{ {
@@ -387,8 +387,8 @@ namespace Ryujinx.Common.Memory
Array38<T> _other; Array38<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 39; public int Length => 39;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 39); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 39);
} }
public struct Array40<T> : IArray<T> where T : unmanaged public struct Array40<T> : IArray<T> where T : unmanaged
{ {
@@ -397,8 +397,8 @@ namespace Ryujinx.Common.Memory
Array39<T> _other; Array39<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 40; public int Length => 40;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 40); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 40);
} }
public struct Array41<T> : IArray<T> where T : unmanaged public struct Array41<T> : IArray<T> where T : unmanaged
{ {
@@ -407,8 +407,8 @@ namespace Ryujinx.Common.Memory
Array40<T> _other; Array40<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 41; public int Length => 41;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 41); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 41);
} }
public struct Array42<T> : IArray<T> where T : unmanaged public struct Array42<T> : IArray<T> where T : unmanaged
{ {
@@ -417,8 +417,8 @@ namespace Ryujinx.Common.Memory
Array41<T> _other; Array41<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 42; public int Length => 42;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 42); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 42);
} }
public struct Array43<T> : IArray<T> where T : unmanaged public struct Array43<T> : IArray<T> where T : unmanaged
{ {
@@ -427,8 +427,8 @@ namespace Ryujinx.Common.Memory
Array42<T> _other; Array42<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 43; public int Length => 43;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 43); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 43);
} }
public struct Array44<T> : IArray<T> where T : unmanaged public struct Array44<T> : IArray<T> where T : unmanaged
{ {
@@ -437,8 +437,8 @@ namespace Ryujinx.Common.Memory
Array43<T> _other; Array43<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 44; public int Length => 44;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 44); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 44);
} }
public struct Array45<T> : IArray<T> where T : unmanaged public struct Array45<T> : IArray<T> where T : unmanaged
{ {
@@ -447,8 +447,8 @@ namespace Ryujinx.Common.Memory
Array44<T> _other; Array44<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 45; public int Length => 45;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 45); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 45);
} }
public struct Array46<T> : IArray<T> where T : unmanaged public struct Array46<T> : IArray<T> where T : unmanaged
{ {
@@ -457,8 +457,8 @@ namespace Ryujinx.Common.Memory
Array45<T> _other; Array45<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 46; public int Length => 46;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 46); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 46);
} }
public struct Array47<T> : IArray<T> where T : unmanaged public struct Array47<T> : IArray<T> where T : unmanaged
{ {
@@ -467,8 +467,8 @@ namespace Ryujinx.Common.Memory
Array46<T> _other; Array46<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 47; public int Length => 47;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 47); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 47);
} }
public struct Array48<T> : IArray<T> where T : unmanaged public struct Array48<T> : IArray<T> where T : unmanaged
{ {
@@ -477,8 +477,8 @@ namespace Ryujinx.Common.Memory
Array47<T> _other; Array47<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 48; public int Length => 48;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 48); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 48);
} }
public struct Array49<T> : IArray<T> where T : unmanaged public struct Array49<T> : IArray<T> where T : unmanaged
{ {
@@ -487,8 +487,8 @@ namespace Ryujinx.Common.Memory
Array48<T> _other; Array48<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 49; public int Length => 49;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 49); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 49);
} }
public struct Array50<T> : IArray<T> where T : unmanaged public struct Array50<T> : IArray<T> where T : unmanaged
{ {
@@ -497,8 +497,8 @@ namespace Ryujinx.Common.Memory
Array49<T> _other; Array49<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 50; public int Length => 50;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 50); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 50);
} }
public struct Array51<T> : IArray<T> where T : unmanaged public struct Array51<T> : IArray<T> where T : unmanaged
{ {
@@ -507,8 +507,8 @@ namespace Ryujinx.Common.Memory
Array50<T> _other; Array50<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 51; public int Length => 51;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 51); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 51);
} }
public struct Array52<T> : IArray<T> where T : unmanaged public struct Array52<T> : IArray<T> where T : unmanaged
{ {
@@ -517,8 +517,8 @@ namespace Ryujinx.Common.Memory
Array51<T> _other; Array51<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 52; public int Length => 52;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 52); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 52);
} }
public struct Array53<T> : IArray<T> where T : unmanaged public struct Array53<T> : IArray<T> where T : unmanaged
{ {
@@ -527,8 +527,8 @@ namespace Ryujinx.Common.Memory
Array52<T> _other; Array52<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 53; public int Length => 53;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 53); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 53);
} }
public struct Array54<T> : IArray<T> where T : unmanaged public struct Array54<T> : IArray<T> where T : unmanaged
{ {
@@ -537,8 +537,8 @@ namespace Ryujinx.Common.Memory
Array53<T> _other; Array53<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 54; public int Length => 54;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 54); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 54);
} }
public struct Array55<T> : IArray<T> where T : unmanaged public struct Array55<T> : IArray<T> where T : unmanaged
{ {
@@ -547,8 +547,8 @@ namespace Ryujinx.Common.Memory
Array54<T> _other; Array54<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 55; public int Length => 55;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 55); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 55);
} }
public struct Array56<T> : IArray<T> where T : unmanaged public struct Array56<T> : IArray<T> where T : unmanaged
{ {
@@ -557,8 +557,8 @@ namespace Ryujinx.Common.Memory
Array55<T> _other; Array55<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 56; public int Length => 56;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 56); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 56);
} }
public struct Array57<T> : IArray<T> where T : unmanaged public struct Array57<T> : IArray<T> where T : unmanaged
{ {
@@ -567,8 +567,8 @@ namespace Ryujinx.Common.Memory
Array56<T> _other; Array56<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 57; public int Length => 57;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 57); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 57);
} }
public struct Array58<T> : IArray<T> where T : unmanaged public struct Array58<T> : IArray<T> where T : unmanaged
{ {
@@ -577,8 +577,8 @@ namespace Ryujinx.Common.Memory
Array57<T> _other; Array57<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 58; public int Length => 58;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 58); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 58);
} }
public struct Array59<T> : IArray<T> where T : unmanaged public struct Array59<T> : IArray<T> where T : unmanaged
{ {
@@ -587,8 +587,8 @@ namespace Ryujinx.Common.Memory
Array58<T> _other; Array58<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 59; public int Length => 59;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 59); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 59);
} }
public struct Array60<T> : IArray<T> where T : unmanaged public struct Array60<T> : IArray<T> where T : unmanaged
{ {
@@ -597,8 +597,8 @@ namespace Ryujinx.Common.Memory
Array59<T> _other; Array59<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 60; public int Length => 60;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 60); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 60);
} }
public struct Array61<T> : IArray<T> where T : unmanaged public struct Array61<T> : IArray<T> where T : unmanaged
{ {
@@ -607,8 +607,8 @@ namespace Ryujinx.Common.Memory
Array60<T> _other; Array60<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 61; public int Length => 61;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 61); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 61);
} }
public struct Array62<T> : IArray<T> where T : unmanaged public struct Array62<T> : IArray<T> where T : unmanaged
{ {
@@ -617,8 +617,8 @@ namespace Ryujinx.Common.Memory
Array61<T> _other; Array61<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 62; public int Length => 62;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 62); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 62);
} }
public struct Array63<T> : IArray<T> where T : unmanaged public struct Array63<T> : IArray<T> where T : unmanaged
{ {
@@ -627,8 +627,8 @@ namespace Ryujinx.Common.Memory
Array62<T> _other; Array62<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 63; public int Length => 63;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 63); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 63);
} }
public struct Array64<T> : IArray<T> where T : unmanaged public struct Array64<T> : IArray<T> where T : unmanaged
{ {
@@ -637,8 +637,8 @@ namespace Ryujinx.Common.Memory
Array63<T> _other; Array63<T> _other;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 64; public int Length => 64;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 64); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 64);
} }
public struct Array73<T> : IArray<T> where T : unmanaged public struct Array73<T> : IArray<T> where T : unmanaged
{ {
@@ -648,7 +648,7 @@ namespace Ryujinx.Common.Memory
Array8<T> _other2; Array8<T> _other2;
#pragma warning restore CS0169 #pragma warning restore CS0169
public int Length => 73; public int Length => 73;
public ref T this[int index] => ref ToSpan()[index]; public ref T this[int index] => ref AsSpan()[index];
public Span<T> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 73); public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 73);
} }
} }

View File

@@ -11,8 +11,8 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
[StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)]
@@ -23,8 +23,8 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
[StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)]
@@ -35,8 +35,8 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
[StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)]
@@ -47,8 +47,8 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
[StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)]
@@ -59,8 +59,8 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
[StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = Size, Pack = 1)]
@@ -71,7 +71,7 @@ namespace Ryujinx.Common.Memory
byte _element; byte _element;
public int Length => Size; public int Length => Size;
public ref byte this[int index] => ref ToSpan()[index]; public ref byte this[int index] => ref AsSpan()[index];
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref _element, Size); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref _element, Size);
} }
} }

View File

@@ -56,7 +56,6 @@ namespace Ryujinx.Graphics.GAL
D32Float, D32Float,
D24UnormS8Uint, D24UnormS8Uint,
D32FloatS8Uint, D32FloatS8Uint,
R8G8B8X8Srgb,
R8G8B8A8Srgb, R8G8B8A8Srgb,
R4G4Unorm, R4G4Unorm,
R4G4B4A4Unorm, R4G4B4A4Unorm,
@@ -113,18 +112,6 @@ namespace Ryujinx.Graphics.GAL
R10G10B10A2Sint, R10G10B10A2Sint,
R10G10B10A2Uscaled, R10G10B10A2Uscaled,
R10G10B10A2Sscaled, R10G10B10A2Sscaled,
R8G8B8X8Unorm,
R8G8B8X8Snorm,
R8G8B8X8Uint,
R8G8B8X8Sint,
R16G16B16X16Float,
R16G16B16X16Unorm,
R16G16B16X16Snorm,
R16G16B16X16Uint,
R16G16B16X16Sint,
R32G32B32X32Float,
R32G32B32X32Uint,
R32G32B32X32Sint,
Astc4x4Unorm, Astc4x4Unorm,
Astc5x4Unorm, Astc5x4Unorm,
Astc5x5Unorm, Astc5x5Unorm,
@@ -154,12 +141,9 @@ namespace Ryujinx.Graphics.GAL
Astc12x10Srgb, Astc12x10Srgb,
Astc12x12Srgb, Astc12x12Srgb,
B5G6R5Unorm, B5G6R5Unorm,
B5G5R5X1Unorm,
B5G5R5A1Unorm, B5G5R5A1Unorm,
A1B5G5R5Unorm, A1B5G5R5Unorm,
B8G8R8X8Unorm,
B8G8R8A8Unorm, B8G8R8A8Unorm,
B8G8R8X8Srgb,
B8G8R8A8Srgb B8G8R8A8Srgb
} }
@@ -272,7 +256,6 @@ namespace Ryujinx.Graphics.GAL
case Format.R8Snorm: case Format.R8Snorm:
case Format.R8Sint: case Format.R8Sint:
case Format.R8Uint: case Format.R8Uint:
case Format.B5G5R5X1Unorm:
return true; return true;
} }
@@ -357,11 +340,8 @@ namespace Ryujinx.Graphics.GAL
switch (format) switch (format)
{ {
case Format.B5G6R5Unorm: case Format.B5G6R5Unorm:
case Format.B5G5R5X1Unorm:
case Format.B5G5R5A1Unorm: case Format.B5G5R5A1Unorm:
case Format.B8G8R8X8Unorm:
case Format.B8G8R8A8Unorm: case Format.B8G8R8A8Unorm:
case Format.B8G8R8X8Srgb:
case Format.B8G8R8A8Srgb: case Format.B8G8R8A8Srgb:
return true; return true;
} }
@@ -412,9 +392,6 @@ namespace Ryujinx.Graphics.GAL
case Format.R16G16B16A16Uint: case Format.R16G16B16A16Uint:
case Format.R32G32B32A32Uint: case Format.R32G32B32A32Uint:
case Format.R10G10B10A2Uint: case Format.R10G10B10A2Uint:
case Format.R8G8B8X8Uint:
case Format.R16G16B16X16Uint:
case Format.R32G32B32X32Uint:
return true; return true;
} }
@@ -443,9 +420,6 @@ namespace Ryujinx.Graphics.GAL
case Format.R16G16B16A16Sint: case Format.R16G16B16A16Sint:
case Format.R32G32B32A32Sint: case Format.R32G32B32A32Sint:
case Format.R10G10B10A2Sint: case Format.R10G10B10A2Sint:
case Format.R8G8B8X8Sint:
case Format.R16G16B16X16Sint:
case Format.R32G32B32X32Sint:
return true; return true;
} }

View File

@@ -13,13 +13,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
public void Set(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel) public void Set(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
{ {
_vertices = vertices; _vertices = vertices;
defaultOuterLevel.CopyTo(_defaultOuterLevel.ToSpan()); defaultOuterLevel.CopyTo(_defaultOuterLevel.AsSpan());
defaultInnerLevel.CopyTo(_defaultInnerLevel.ToSpan()); defaultInnerLevel.CopyTo(_defaultInnerLevel.AsSpan());
} }
public static void Run(ref SetPatchParametersCommand command, ThreadedRenderer threaded, IRenderer renderer) public static void Run(ref SetPatchParametersCommand command, ThreadedRenderer threaded, IRenderer renderer)
{ {
renderer.Pipeline.SetPatchParameters(command._vertices, command._defaultOuterLevel.ToSpan(), command._defaultInnerLevel.ToSpan()); renderer.Pipeline.SetPatchParameters(command._vertices, command._defaultOuterLevel.AsSpan(), command._defaultInnerLevel.AsSpan());
} }
} }
} }

View File

@@ -66,7 +66,7 @@ namespace Ryujinx.Graphics.GAL
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs) public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
{ {
VertexAttribCount = vertexAttribs.Length; VertexAttribCount = vertexAttribs.Length;
vertexAttribs.CopyTo(VertexAttribs.ToSpan()); vertexAttribs.CopyTo(VertexAttribs.AsSpan());
} }
public void SetLogicOpState(bool enable, LogicalOp op) public void SetLogicOpState(bool enable, LogicalOp op)

View File

@@ -65,12 +65,12 @@ namespace Ryujinx.Graphics.GAL
public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count) public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count)
{ {
UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.ToSpan(), offset, count); UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.AsSpan(), offset, count);
} }
public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count) public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count)
{ {
UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.ToSpan(), offset, count); UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.AsSpan(), offset, count);
} }
public void UpdateViewportInverse(Vector4<float> data) public void UpdateViewportInverse(Vector4<float> data)

View File

@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
#pragma warning disable CS0169 #pragma warning disable CS0169
private uint _e0; private uint _e0;
#pragma warning restore CS0169 #pragma warning restore CS0169
public ref uint this[int index] => ref ToSpan()[index]; public ref uint this[int index] => ref AsSpan()[index];
public Span<uint> ToSpan() => MemoryMarshal.CreateSpan(ref _e0, 256); public Span<uint> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 256);
} }
} }

View File

@@ -42,6 +42,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private uint _prevFirstVertex; private uint _prevFirstVertex;
private bool _prevTfEnable; private bool _prevTfEnable;
private uint _prevRtNoAlphaMask;
/// <summary> /// <summary>
/// Creates a new instance of the state updater. /// Creates a new instance of the state updater.
/// </summary> /// </summary>
@@ -331,8 +333,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_context.Renderer.Pipeline.SetPatchParameters( _context.Renderer.Pipeline.SetPatchParameters(
_state.State.PatchVertices, _state.State.PatchVertices,
_state.State.TessOuterLevel.ToSpan(), _state.State.TessOuterLevel.AsSpan(),
_state.State.TessInnerLevel.ToSpan()); _state.State.TessInnerLevel.AsSpan());
} }
/// <summary> /// <summary>
@@ -398,6 +400,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
int clipRegionHeight = int.MaxValue; int clipRegionHeight = int.MaxValue;
bool changedScale = false; bool changedScale = false;
uint rtNoAlphaMask = 0;
for (int index = 0; index < Constants.TotalRenderTargets; index++) for (int index = 0; index < Constants.TotalRenderTargets; index++)
{ {
@@ -412,6 +415,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
continue; continue;
} }
if (colorState.Format.NoAlpha())
{
rtNoAlphaMask |= 1u << index;
}
Image.Texture color = memoryManager.Physical.TextureCache.FindOrCreateTexture( Image.Texture color = memoryManager.Physical.TextureCache.FindOrCreateTexture(
memoryManager, memoryManager,
colorState, colorState,
@@ -485,6 +493,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
} }
_channel.TextureManager.SetClipRegion(clipRegionWidth, clipRegionHeight); _channel.TextureManager.SetClipRegion(clipRegionWidth, clipRegionHeight);
if (useControl && _prevRtNoAlphaMask != rtNoAlphaMask)
{
_prevRtNoAlphaMask = rtNoAlphaMask;
UpdateBlendState();
}
} }
/// <summary> /// <summary>
@@ -1056,45 +1071,81 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
bool blendIndependent = _state.State.BlendIndependent; bool blendIndependent = _state.State.BlendIndependent;
ColorF blendConstant = _state.State.BlendConstant; ColorF blendConstant = _state.State.BlendConstant;
for (int index = 0; index < Constants.TotalRenderTargets; index++)
{
BlendDescriptor descriptor;
if (blendIndependent) if (blendIndependent)
{
for (int index = 0; index < Constants.TotalRenderTargets; index++)
{ {
bool enable = _state.State.BlendEnable[index]; bool enable = _state.State.BlendEnable[index];
var blend = _state.State.BlendState[index]; var blend = _state.State.BlendState[index];
descriptor = new BlendDescriptor( var descriptor = new BlendDescriptor(
enable, enable,
blendConstant, blendConstant,
blend.ColorOp, blend.ColorOp,
blend.ColorSrcFactor, FilterBlendFactor(blend.ColorSrcFactor, index),
blend.ColorDstFactor, FilterBlendFactor(blend.ColorDstFactor, index),
blend.AlphaOp, blend.AlphaOp,
blend.AlphaSrcFactor, FilterBlendFactor(blend.AlphaSrcFactor, index),
blend.AlphaDstFactor); FilterBlendFactor(blend.AlphaDstFactor, index));
_pipeline.BlendDescriptors[index] = descriptor;
_context.Renderer.Pipeline.SetBlendState(index, descriptor);
}
} }
else else
{ {
bool enable = _state.State.BlendEnable[0]; bool enable = _state.State.BlendEnable[0];
var blend = _state.State.BlendStateCommon; var blend = _state.State.BlendStateCommon;
descriptor = new BlendDescriptor( var descriptor = new BlendDescriptor(
enable, enable,
blendConstant, blendConstant,
blend.ColorOp, blend.ColorOp,
blend.ColorSrcFactor, FilterBlendFactor(blend.ColorSrcFactor, 0),
blend.ColorDstFactor, FilterBlendFactor(blend.ColorDstFactor, 0),
blend.AlphaOp, blend.AlphaOp,
blend.AlphaSrcFactor, FilterBlendFactor(blend.AlphaSrcFactor, 0),
blend.AlphaDstFactor); FilterBlendFactor(blend.AlphaDstFactor, 0));
}
for (int index = 0; index < Constants.TotalRenderTargets; index++)
{
_pipeline.BlendDescriptors[index] = descriptor; _pipeline.BlendDescriptors[index] = descriptor;
_context.Renderer.Pipeline.SetBlendState(index, descriptor); _context.Renderer.Pipeline.SetBlendState(index, descriptor);
} }
} }
}
/// <summary>
/// Gets a blend factor for the color target currently.
/// This will return <paramref name="factor"/> unless the target format has no alpha component,
/// in which case it will replace destination alpha factor with a constant factor of one or zero.
/// </summary>
/// <param name="factor">Input factor</param>
/// <param name="index">Color target index</param>
/// <returns>New blend factor</returns>
private BlendFactor FilterBlendFactor(BlendFactor factor, int index)
{
// If any color target format without alpha is being used, we need to make sure that
// if blend is active, it will not use destination alpha as a factor.
// That is required because RGBX formats are emulated using host RGBA formats.
if (_state.State.RtColorState[index].Format.NoAlpha())
{
switch (factor)
{
case BlendFactor.DstAlpha:
case BlendFactor.DstAlphaGl:
factor = BlendFactor.One;
break;
case BlendFactor.OneMinusDstAlpha:
case BlendFactor.OneMinusDstAlphaGl:
factor = BlendFactor.Zero;
break;
}
}
return factor;
}
/// <summary> /// <summary>
/// Updates host logical operation state, based on guest state. /// Updates host logical operation state, based on guest state.
@@ -1242,6 +1293,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_channel.BufferManager.SetGraphicsUniformBufferBindings(stage, info.CBuffers); _channel.BufferManager.SetGraphicsUniformBufferBindings(stage, info.CBuffers);
} }
/// <summary>
/// Gets the current texture pool state.
/// </summary>
/// <returns>Texture pool state</returns>
private GpuChannelPoolState GetPoolState() private GpuChannelPoolState GetPoolState()
{ {
return new GpuChannelPoolState( return new GpuChannelPoolState(
@@ -1286,6 +1341,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
ref attributeTypes); ref attributeTypes);
} }
/// <summary>
/// Gets the depth mode that is currently being used (zero to one or minus one to one).
/// </summary>
/// <returns>Current depth mode</returns>
private DepthMode GetDepthMode() private DepthMode GetDepthMode()
{ {
ref var transform = ref _state.State.ViewportTransform[0]; ref var transform = ref _state.State.ViewportTransform[0];

View File

@@ -124,11 +124,42 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
ColorFormat.R8Snorm => new FormatInfo(Format.R8Snorm, 1, 1, 1, 1), ColorFormat.R8Snorm => new FormatInfo(Format.R8Snorm, 1, 1, 1, 1),
ColorFormat.R8Sint => new FormatInfo(Format.R8Sint, 1, 1, 1, 1), ColorFormat.R8Sint => new FormatInfo(Format.R8Sint, 1, 1, 1, 1),
ColorFormat.R8Uint => new FormatInfo(Format.R8Uint, 1, 1, 1, 1), ColorFormat.R8Uint => new FormatInfo(Format.R8Uint, 1, 1, 1, 1),
ColorFormat.B5G5R5X1Unorm => new FormatInfo(Format.B5G5R5X1Unorm, 1, 1, 2, 4), ColorFormat.B5G5R5X1Unorm => new FormatInfo(Format.B5G5R5A1Unorm, 1, 1, 2, 4),
ColorFormat.R8G8B8X8Unorm => new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4), ColorFormat.R8G8B8X8Unorm => new FormatInfo(Format.R8G8B8A8Unorm, 1, 1, 4, 4),
ColorFormat.R8G8B8X8Srgb => new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4), ColorFormat.R8G8B8X8Srgb => new FormatInfo(Format.R8G8B8A8Srgb, 1, 1, 4, 4),
_ => FormatInfo.Default _ => FormatInfo.Default
}; };
} }
/// <summary>
/// Checks if a format has an alpha component.
/// </summary>
/// <param name="format">Format to be checked</param>
/// <returns>True if the format has no alpha component (RGBX), false if it does (RGBA)</returns>
public static bool NoAlpha(this ColorFormat format)
{
switch (format)
{
case ColorFormat.R32G32B32X32Float:
case ColorFormat.R32G32B32X32Sint:
case ColorFormat.R32G32B32X32Uint:
case ColorFormat.R16G16B16X16Unorm:
case ColorFormat.R16G16B16X16Snorm:
case ColorFormat.R16G16B16X16Sint:
case ColorFormat.R16G16B16X16Uint:
case ColorFormat.R16G16B16X16Float:
case ColorFormat.R8G8B8X8Snorm:
case ColorFormat.R8G8B8X8Sint:
case ColorFormat.R8G8B8X8Uint:
case ColorFormat.B8G8R8X8Unorm:
case ColorFormat.B8G8R8X8Srgb:
case ColorFormat.B5G5R5X1Unorm:
case ColorFormat.R8G8B8X8Unorm:
case ColorFormat.R8G8B8X8Srgb:
return true;
}
return false;
}
} }
} }

View File

@@ -553,7 +553,7 @@ namespace Ryujinx.Graphics.Gpu.Image
specStateMatches &= specState.MatchesTexture(stage, index, descriptor); specStateMatches &= specState.MatchesTexture(stage, index, descriptor);
Sampler sampler = _samplerPool?.Get(samplerId); Sampler sampler = samplerPool?.Get(samplerId);
ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target); ITexture hostTexture = texture?.GetTargetTexture(bindingInfo.Target);
ISampler hostSampler = sampler?.GetHostSampler(texture); ISampler hostSampler = sampler?.GetHostSampler(texture);

View File

@@ -515,7 +515,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
return false; return false;
} }
if (!graphicsState.AttributeTypes.ToSpan().SequenceEqual(GraphicsState.AttributeTypes.ToSpan())) if (!graphicsState.AttributeTypes.AsSpan().SequenceEqual(GraphicsState.AttributeTypes.AsSpan()))
{ {
return false; return false;
} }

View File

@@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <returns>Span of varying locations</returns> /// <returns>Span of varying locations</returns>
public ReadOnlySpan<byte> AsSpan() public ReadOnlySpan<byte> AsSpan()
{ {
return MemoryMarshal.Cast<uint, byte>(VaryingLocations.ToSpan()).Slice(0, Math.Min(128, VaryingCount)); return MemoryMarshal.Cast<uint, byte>(VaryingLocations.AsSpan()).Slice(0, Math.Min(128, VaryingCount));
} }
} }
} }

View File

@@ -30,23 +30,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst); Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst);
if (xd.Lossless) if (xd.Lossless)
{ {
Idct.HighbdIwht4x4Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIwht4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
} }
else else
{ {
switch (txSize) switch (txSize)
{ {
case TxSize.Tx4x4: case TxSize.Tx4x4:
Idct.HighbdIdct4x4Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIdct4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx8x8: case TxSize.Tx8x8:
Idct.HighbdIdct8x8Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIdct8x8Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx16x16: case TxSize.Tx16x16:
Idct.HighbdIdct16x16Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIdct16x16Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx32x32: case TxSize.Tx32x32:
Idct.HighbdIdct32x32Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
default: Debug.Assert(false, "Invalid transform size"); break; default: Debug.Assert(false, "Invalid transform size"); break;
} }
@@ -56,16 +56,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
if (xd.Lossless) if (xd.Lossless)
{ {
Idct.Iwht4x4Add(dqcoeff.ToSpan(), dst, stride, eob); Idct.Iwht4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
} }
else else
{ {
switch (txSize) switch (txSize)
{ {
case TxSize.Tx4x4: Idct.Idct4x4Add(dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx4x4: Idct.Idct4x4Add(dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx8x8: Idct.Idct8x8Add(dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx8x8: Idct.Idct8x8Add(dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx16x16: Idct.Idct16x16Add(dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx16x16: Idct.Idct16x16Add(dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob); break;
default: Debug.Assert(false, "Invalid transform size"); return; default: Debug.Assert(false, "Invalid transform size"); return;
} }
} }
@@ -73,21 +73,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
if (eob == 1) if (eob == 1)
{ {
dqcoeff.ToSpan()[0] = 0; dqcoeff.AsSpan()[0] = 0;
} }
else else
{ {
if (txSize <= TxSize.Tx16x16 && eob <= 10) if (txSize <= TxSize.Tx16x16 && eob <= 10)
{ {
dqcoeff.ToSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0); dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0);
} }
else if (txSize == TxSize.Tx32x32 && eob <= 34) else if (txSize == TxSize.Tx32x32 && eob <= 34)
{ {
dqcoeff.ToSpan().Slice(0, 256).Fill(0); dqcoeff.AsSpan().Slice(0, 256).Fill(0);
} }
else else
{ {
dqcoeff.ToSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0); dqcoeff.AsSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0);
} }
} }
} }
@@ -109,23 +109,23 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst); Span<ushort> dst16 = MemoryMarshal.Cast<byte, ushort>(dst);
if (xd.Lossless) if (xd.Lossless)
{ {
Idct.HighbdIwht4x4Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIwht4x4Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
} }
else else
{ {
switch (txSize) switch (txSize)
{ {
case TxSize.Tx4x4: case TxSize.Tx4x4:
Idct.HighbdIht4x4Add(txType, dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIht4x4Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx8x8: case TxSize.Tx8x8:
Idct.HighbdIht8x8Add(txType, dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIht8x8Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx16x16: case TxSize.Tx16x16:
Idct.HighbdIht16x16Add(txType, dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIht16x16Add(txType, dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
case TxSize.Tx32x32: case TxSize.Tx32x32:
Idct.HighbdIdct32x32Add(dqcoeff.ToSpan(), dst16, stride, eob, xd.Bd); Idct.HighbdIdct32x32Add(dqcoeff.AsSpan(), dst16, stride, eob, xd.Bd);
break; break;
default: Debug.Assert(false, "Invalid transform size"); break; default: Debug.Assert(false, "Invalid transform size"); break;
} }
@@ -135,16 +135,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
if (xd.Lossless) if (xd.Lossless)
{ {
Idct.Iwht4x4Add(dqcoeff.ToSpan(), dst, stride, eob); Idct.Iwht4x4Add(dqcoeff.AsSpan(), dst, stride, eob);
} }
else else
{ {
switch (txSize) switch (txSize)
{ {
case TxSize.Tx4x4: Idct.Iht4x4Add(txType, dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx4x4: Idct.Iht4x4Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx8x8: Idct.Iht8x8Add(txType, dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx8x8: Idct.Iht8x8Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx16x16: Idct.Iht16x16Add(txType, dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx16x16: Idct.Iht16x16Add(txType, dqcoeff.AsSpan(), dst, stride, eob); break;
case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.ToSpan(), dst, stride, eob); break; case TxSize.Tx32x32: Idct.Idct32x32Add(dqcoeff.AsSpan(), dst, stride, eob); break;
default: Debug.Assert(false, "Invalid transform size"); return; default: Debug.Assert(false, "Invalid transform size"); return;
} }
} }
@@ -152,21 +152,21 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
if (eob == 1) if (eob == 1)
{ {
dqcoeff.ToSpan()[0] = 0; dqcoeff.AsSpan()[0] = 0;
} }
else else
{ {
if (txType == TxType.DctDct && txSize <= TxSize.Tx16x16 && eob <= 10) if (txType == TxType.DctDct && txSize <= TxSize.Tx16x16 && eob <= 10)
{ {
dqcoeff.ToSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0); dqcoeff.AsSpan().Slice(0, 4 * (4 << (int)txSize)).Fill(0);
} }
else if (txSize == TxSize.Tx32x32 && eob <= 34) else if (txSize == TxSize.Tx32x32 && eob <= 34)
{ {
dqcoeff.ToSpan().Slice(0, 256).Fill(0); dqcoeff.AsSpan().Slice(0, 256).Fill(0);
} }
else else
{ {
dqcoeff.ToSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0); dqcoeff.AsSpan().Slice(0, 16 << ((int)txSize << 1)).Fill(0);
} }
} }
} }
@@ -184,7 +184,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
PredictionMode mode = (plane == 0) ? mi.Mode : mi.UvMode; PredictionMode mode = (plane == 0) ? mi.Mode : mi.UvMode;
int dstOffset = 4 * row * pd.Dst.Stride + 4 * col; int dstOffset = 4 * row * pd.Dst.Stride + 4 * col;
byte* dst = &pd.Dst.Buf.ToPointer()[dstOffset]; byte* dst = &pd.Dst.Buf.ToPointer()[dstOffset];
Span<byte> dstSpan = pd.Dst.Buf.ToSpan().Slice(dstOffset); Span<byte> dstSpan = pd.Dst.Buf.AsSpan().Slice(dstOffset);
if (mi.SbType < BlockSize.Block8x8) if (mi.SbType < BlockSize.Block8x8)
{ {
@@ -223,7 +223,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
ref MacroBlockDPlane pd = ref xd.Plane[plane]; ref MacroBlockDPlane pd = ref xd.Plane[plane];
var sc = Luts.Vp9DefaultScanOrders[(int)txSize]; var sc = Luts.Vp9DefaultScanOrders[(int)txSize];
int eob = Detokenize.DecodeBlockTokens(ref twd, plane, sc, col, row, txSize, mi.SegmentId); int eob = Detokenize.DecodeBlockTokens(ref twd, plane, sc, col, row, txSize, mi.SegmentId);
Span<byte> dst = pd.Dst.Buf.ToSpan().Slice(4 * row * pd.Dst.Stride + 4 * col); Span<byte> dst = pd.Dst.Buf.AsSpan().Slice(4 * row * pd.Dst.Stride + 4 * col);
if (eob > 0) if (eob > 0)
{ {
@@ -922,7 +922,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
BlockSize subsize, BlockSize subsize,
int bw) int bw)
{ {
Span<sbyte> aboveCtx = twd.Xd.AboveSegContext.Slice(miCol).ToSpan(); Span<sbyte> aboveCtx = twd.Xd.AboveSegContext.Slice(miCol).AsSpan();
Span<sbyte> leftCtx = MemoryMarshal.CreateSpan(ref twd.Xd.LeftSegContext[miRow & Constants.MiMask], 8 - (miRow & Constants.MiMask)); Span<sbyte> leftCtx = MemoryMarshal.CreateSpan(ref twd.Xd.LeftSegContext[miRow & Constants.MiMask], 8 - (miRow & Constants.MiMask));
// Update the partition context at the end notes. Set partition bits // Update the partition context at the end notes. Set partition bits
@@ -1077,7 +1077,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
errorInfo.InternalError(CodecErr.CodecCorruptFrame, "Truncated packet or corrupt tile length"); errorInfo.InternalError(CodecErr.CodecCorruptFrame, "Truncated packet or corrupt tile length");
} }
size = BinaryPrimitives.ReadInt32BigEndian(data.ToSpan()); size = BinaryPrimitives.ReadInt32BigEndian(data.AsSpan());
data = data.Slice(4); data = data.Slice(4);
if (size > data.Length) if (size > data.Length)
@@ -1250,8 +1250,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
Debug.Assert(tileCols <= (1 << 6)); Debug.Assert(tileCols <= (1 << 6));
Debug.Assert(tileRows == 1); Debug.Assert(tileRows == 1);
cm.AboveContext.ToSpan().Fill(0); cm.AboveContext.AsSpan().Fill(0);
cm.AboveSegContext.ToSpan().Fill(0); cm.AboveSegContext.AsSpan().Fill(0);
for (n = 0; n < numWorkers; ++n) for (n = 0; n < numWorkers; ++n)
{ {
@@ -1266,12 +1266,12 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
GetTileBuffers(ref cm, data, tileCols, ref tileBuffers); GetTileBuffers(ref cm, data, tileCols, ref tileBuffers);
tileBuffers.ToSpan().Slice(0, tileCols).Sort(CompareTileBuffers); tileBuffers.AsSpan().Slice(0, tileCols).Sort(CompareTileBuffers);
if (numWorkers == tileCols) if (numWorkers == tileCols)
{ {
TileBuffer largest = tileBuffers[0]; TileBuffer largest = tileBuffers[0];
Span<TileBuffer> buffers = tileBuffers.ToSpan(); Span<TileBuffer> buffers = tileBuffers.AsSpan();
buffers.Slice(1).CopyTo(buffers.Slice(0, tileBuffers.Length - 1)); buffers.Slice(1).CopyTo(buffers.Slice(0, tileBuffers.Length - 1));
tileBuffers[tileCols - 1] = largest; tileBuffers[tileCols - 1] = largest;
} }

View File

@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
private static PredictionMode ReadIntraModeY(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int sizeGroup) private static PredictionMode ReadIntraModeY(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int sizeGroup)
{ {
PredictionMode yMode = ReadIntraMode(ref r, cm.Fc.Value.YModeProb[sizeGroup].ToSpan()); PredictionMode yMode = ReadIntraMode(ref r, cm.Fc.Value.YModeProb[sizeGroup].AsSpan());
if (!xd.Counts.IsNull) if (!xd.Counts.IsNull)
{ {
++xd.Counts.Value.YMode[sizeGroup][(int)yMode]; ++xd.Counts.Value.YMode[sizeGroup][(int)yMode];
@@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
private static PredictionMode ReadIntraModeUv(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, byte yMode) private static PredictionMode ReadIntraModeUv(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, byte yMode)
{ {
PredictionMode uvMode = ReadIntraMode(ref r, cm.Fc.Value.UvModeProb[yMode].ToSpan()); PredictionMode uvMode = ReadIntraMode(ref r, cm.Fc.Value.UvModeProb[yMode].AsSpan());
if (!xd.Counts.IsNull) if (!xd.Counts.IsNull)
{ {
++xd.Counts.Value.UvMode[yMode][(int)uvMode]; ++xd.Counts.Value.UvMode[yMode][(int)uvMode];
@@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
private static PredictionMode ReadInterMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int ctx) private static PredictionMode ReadInterMode(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r, int ctx)
{ {
int mode = r.ReadTree(Luts.Vp9InterModeTree, cm.Fc.Value.InterModeProb[ctx].ToSpan()); int mode = r.ReadTree(Luts.Vp9InterModeTree, cm.Fc.Value.InterModeProb[ctx].AsSpan());
if (!xd.Counts.IsNull) if (!xd.Counts.IsNull)
{ {
++xd.Counts.Value.InterMode[ctx][mode]; ++xd.Counts.Value.InterMode[ctx][mode];
@@ -54,16 +54,16 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
private static int ReadSegmentId(ref Reader r, ref Array7<byte> segTreeProbs) private static int ReadSegmentId(ref Reader r, ref Array7<byte> segTreeProbs)
{ {
return r.ReadTree(Luts.Vp9SegmentTree, segTreeProbs.ToSpan()); return r.ReadTree(Luts.Vp9SegmentTree, segTreeProbs.AsSpan());
} }
private static ReadOnlySpan<byte> GetTxProbs(ref Vp9EntropyProbs fc, TxSize maxTxSize, int ctx) private static ReadOnlySpan<byte> GetTxProbs(ref Vp9EntropyProbs fc, TxSize maxTxSize, int ctx)
{ {
switch (maxTxSize) switch (maxTxSize)
{ {
case TxSize.Tx8x8: return fc.Tx8x8Prob[ctx].ToSpan(); case TxSize.Tx8x8: return fc.Tx8x8Prob[ctx].AsSpan();
case TxSize.Tx16x16: return fc.Tx16x16Prob[ctx].ToSpan(); case TxSize.Tx16x16: return fc.Tx16x16Prob[ctx].AsSpan();
case TxSize.Tx32x32: return fc.Tx32x32Prob[ctx].ToSpan(); case TxSize.Tx32x32: return fc.Tx32x32Prob[ctx].AsSpan();
default: Debug.Assert(false, "Invalid maxTxSize."); return ReadOnlySpan<byte>.Empty; default: Debug.Assert(false, "Invalid maxTxSize."); return ReadOnlySpan<byte>.Empty;
} }
} }
@@ -72,9 +72,9 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
switch (maxTxSize) switch (maxTxSize)
{ {
case TxSize.Tx8x8: return counts.Tx8x8[ctx].ToSpan(); case TxSize.Tx8x8: return counts.Tx8x8[ctx].AsSpan();
case TxSize.Tx16x16: return counts.Tx16x16[ctx].ToSpan(); case TxSize.Tx16x16: return counts.Tx16x16[ctx].AsSpan();
case TxSize.Tx32x32: return counts.Tx32x32[ctx].ToSpan(); case TxSize.Tx32x32: return counts.Tx32x32[ctx].AsSpan();
default: Debug.Assert(false, "Invalid maxTxSize."); return Span<uint>.Empty; default: Debug.Assert(false, "Invalid maxTxSize."); return Span<uint>.Empty;
} }
} }
@@ -253,7 +253,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
int mag, d, fr, hp; int mag, d, fr, hp;
bool sign = r.Read(fc.Sign[mvcomp]) != 0; bool sign = r.Read(fc.Sign[mvcomp]) != 0;
MvClassType mvClass = (MvClassType)r.ReadTree(Luts.Vp9MvClassTree, fc.Classes[mvcomp].ToSpan()); MvClassType mvClass = (MvClassType)r.ReadTree(Luts.Vp9MvClassTree, fc.Classes[mvcomp].AsSpan());
bool class0 = mvClass == MvClassType.MvClass0; bool class0 = mvClass == MvClassType.MvClass0;
// Integer part // Integer part
@@ -277,7 +277,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
} }
// Fractional part // Fractional part
fr = r.ReadTree(Luts.Vp9MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].ToSpan() : fc.Fp[mvcomp].ToSpan()); fr = r.ReadTree(Luts.Vp9MvFPTree, class0 ? fc.Class0Fp[mvcomp][d].AsSpan() : fc.Fp[mvcomp].AsSpan());
// High precision part (if hp is not used, the default value of the hp is 1) // High precision part (if hp is not used, the default value of the hp is 1)
hp = usehp ? r.Read(class0 ? fc.Class0Hp[mvcomp] : fc.Hp[mvcomp]) : 1; hp = usehp ? r.Read(class0 ? fc.Class0Hp[mvcomp] : fc.Hp[mvcomp]) : 1;
@@ -295,7 +295,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
Ptr<Vp9BackwardUpdates> counts, Ptr<Vp9BackwardUpdates> counts,
bool allowHP) bool allowHP)
{ {
MvJointType jointType = (MvJointType)r.ReadTree(Luts.Vp9MvJointTree, fc.Joints.ToSpan()); MvJointType jointType = (MvJointType)r.ReadTree(Luts.Vp9MvJointTree, fc.Joints.AsSpan());
bool useHP = allowHP && refr.UseMvHp(); bool useHP = allowHP && refr.UseMvHp();
Mv diff = new Mv(); Mv diff = new Mv();
@@ -402,7 +402,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
private static byte ReadSwitchableInterpFilter(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r) private static byte ReadSwitchableInterpFilter(ref Vp9Common cm, ref MacroBlockD xd, ref Reader r)
{ {
int ctx = xd.GetPredContextSwitchableInterp(); int ctx = xd.GetPredContextSwitchableInterp();
byte type = (byte)r.ReadTree(Luts.Vp9SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].ToSpan()); byte type = (byte)r.ReadTree(Luts.Vp9SwitchableInterpTree, cm.Fc.Value.SwitchableInterpProb[ctx].AsSpan());
if (!xd.Counts.IsNull) if (!xd.Counts.IsNull)
{ {
++xd.Counts.Value.SwitchableInterp[ctx][type]; ++xd.Counts.Value.SwitchableInterp[ctx][type];
@@ -1060,7 +1060,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
PredictionMode above = AboveBlockMode(mi, aboveMi, block); PredictionMode above = AboveBlockMode(mi, aboveMi, block);
PredictionMode left = LeftBlockMode(mi, leftMi, block); PredictionMode left = LeftBlockMode(mi, leftMi, block);
return fc.KfYModeProb[(int)above][(int)left].ToSpan(); return fc.KfYModeProb[(int)above][(int)left].AsSpan();
} }
private static void ReadIntraFrameModeInfo( private static void ReadIntraFrameModeInfo(
@@ -1113,7 +1113,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
break; break;
} }
mi.Value.UvMode = ReadIntraMode(ref r, cm.Fc.Value.KfUvModeProb[(int)mi.Value.Mode].ToSpan()); mi.Value.UvMode = ReadIntraMode(ref r, cm.Fc.Value.KfUvModeProb[(int)mi.Value.Mode].AsSpan());
} }
private static void CopyRefFramePair(ref Array2<sbyte> dst, ref Array2<sbyte> src) private static void CopyRefFramePair(ref Array2<sbyte> dst, ref Array2<sbyte> src)

View File

@@ -236,8 +236,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
ref MacroBlockDPlane pd = ref xd.Plane[plane]; ref MacroBlockDPlane pd = ref xd.Plane[plane];
ref Array2<short> dequant = ref pd.SegDequant[segId]; ref Array2<short> dequant = ref pd.SegDequant[segId];
int eob; int eob;
Span<sbyte> a = pd.AboveContext.ToSpan().Slice(x); Span<sbyte> a = pd.AboveContext.AsSpan().Slice(x);
Span<sbyte> l = pd.LeftContext.ToSpan().Slice(y); Span<sbyte> l = pd.LeftContext.AsSpan().Slice(y);
int ctx; int ctx;
int ctxShiftA = 0; int ctxShiftA = 0;
int ctxShiftL = 0; int ctxShiftL = 0;
@@ -250,7 +250,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
eob = DecodeCoefs( eob = DecodeCoefs(
ref xd, ref xd,
GetPlaneType(plane), GetPlaneType(plane),
pd.DqCoeff.ToSpan(), pd.DqCoeff.AsSpan(),
txSize, txSize,
ref dequant, ref dequant,
ctx, ctx,
@@ -266,7 +266,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
eob = DecodeCoefs( eob = DecodeCoefs(
ref xd, ref xd,
GetPlaneType(plane), GetPlaneType(plane),
pd.DqCoeff.ToSpan(), pd.DqCoeff.AsSpan(),
txSize, txSize,
ref dequant, ref dequant,
ctx, ctx,
@@ -283,7 +283,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
eob = DecodeCoefs( eob = DecodeCoefs(
ref xd, ref xd,
GetPlaneType(plane), GetPlaneType(plane),
pd.DqCoeff.ToSpan(), pd.DqCoeff.AsSpan(),
txSize, txSize,
ref dequant, ref dequant,
ctx, ctx,
@@ -303,7 +303,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
eob = DecodeCoefs( eob = DecodeCoefs(
ref xd, ref xd,
GetPlaneType(plane), GetPlaneType(plane),
pd.DqCoeff.ToSpan(), pd.DqCoeff.AsSpan(),
txSize, txSize,
ref dequant, ref dequant,
ctx, ctx,

View File

@@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9.Dsp
private void Fill() private void Fill()
{ {
ReadOnlySpan<byte> buffer = _buffer.ToSpan(); ReadOnlySpan<byte> buffer = _buffer.AsSpan();
ReadOnlySpan<byte> bufferStart = buffer; ReadOnlySpan<byte> bufferStart = buffer;
ulong value = Value; ulong value = Value;
int count = Count; int count = Count;

View File

@@ -359,8 +359,8 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
blockInsideLimit = 1; blockInsideLimit = 1;
} }
lfi.Lfthr[lvl].Lim.ToSpan().Fill((byte)blockInsideLimit); lfi.Lfthr[lvl].Lim.AsSpan().Fill((byte)blockInsideLimit);
lfi.Lfthr[lvl].Mblim.ToSpan().Fill((byte)(2 * (lvl + 2) + blockInsideLimit)); lfi.Lfthr[lvl].Mblim.AsSpan().Fill((byte)(2 * (lvl + 2) + blockInsideLimit));
} }
} }
@@ -395,7 +395,7 @@ namespace Ryujinx.Graphics.Nvdec.Vp9
{ {
// We could get rid of this if we assume that deltas are set to // We could get rid of this if we assume that deltas are set to
// zero when not in use; encoder always uses deltas // zero when not in use; encoder always uses deltas
MemoryMarshal.Cast<Array2<byte>, byte>(lfi.Lvl[segId].ToSpan()).Fill((byte)lvlSeg); MemoryMarshal.Cast<Array2<byte>, byte>(lfi.Lvl[segId].AsSpan()).Fill((byte)lvlSeg);
} }
else else
{ {

View File

@@ -70,7 +70,6 @@ namespace Ryujinx.Graphics.OpenGL
Add(Format.D32Float, new FormatInfo(1, false, false, All.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float)); Add(Format.D32Float, new FormatInfo(1, false, false, All.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float));
Add(Format.D24UnormS8Uint, new FormatInfo(1, false, false, All.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248)); Add(Format.D24UnormS8Uint, new FormatInfo(1, false, false, All.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248));
Add(Format.D32FloatS8Uint, new FormatInfo(1, false, false, All.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev)); Add(Format.D32FloatS8Uint, new FormatInfo(1, false, false, All.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev));
Add(Format.R8G8B8X8Srgb, new FormatInfo(4, false, false, All.Srgb8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.R8G8B8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte)); Add(Format.R8G8B8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.R4G4B4A4Unorm, new FormatInfo(4, true, false, All.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed)); Add(Format.R4G4B4A4Unorm, new FormatInfo(4, true, false, All.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed));
Add(Format.R5G5B5X1Unorm, new FormatInfo(4, true, false, All.Rgb5, PixelFormat.Rgb, PixelType.UnsignedShort1555Reversed)); Add(Format.R5G5B5X1Unorm, new FormatInfo(4, true, false, All.Rgb5, PixelFormat.Rgb, PixelType.UnsignedShort1555Reversed));
@@ -124,18 +123,6 @@ namespace Ryujinx.Graphics.OpenGL
Add(Format.R10G10B10A2Sint, new FormatInfo(4, false, false, All.Rgb10A2, PixelFormat.RgbaInteger, (PixelType)All.Int2101010Rev)); Add(Format.R10G10B10A2Sint, new FormatInfo(4, false, false, All.Rgb10A2, PixelFormat.RgbaInteger, (PixelType)All.Int2101010Rev));
Add(Format.R10G10B10A2Uscaled, new FormatInfo(4, false, true, All.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed)); Add(Format.R10G10B10A2Uscaled, new FormatInfo(4, false, true, All.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed));
Add(Format.R10G10B10A2Sscaled, new FormatInfo(4, false, true, All.Rgb10A2, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed)); Add(Format.R10G10B10A2Sscaled, new FormatInfo(4, false, true, All.Rgb10A2, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed));
Add(Format.R8G8B8X8Unorm, new FormatInfo(4, true, false, All.Rgb8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.R8G8B8X8Snorm, new FormatInfo(4, true, false, All.Rgb8Snorm, PixelFormat.Rgba, PixelType.Byte));
Add(Format.R8G8B8X8Uint, new FormatInfo(4, false, false, All.Rgb8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte));
Add(Format.R8G8B8X8Sint, new FormatInfo(4, false, false, All.Rgb8i, PixelFormat.RgbaInteger, PixelType.Byte));
Add(Format.R16G16B16X16Float, new FormatInfo(4, false, false, All.Rgb16f, PixelFormat.Rgba, PixelType.HalfFloat));
Add(Format.R16G16B16X16Unorm, new FormatInfo(4, true, false, All.Rgb16, PixelFormat.Rgba, PixelType.UnsignedShort));
Add(Format.R16G16B16X16Snorm, new FormatInfo(4, true, false, All.Rgb16Snorm, PixelFormat.Rgba, PixelType.Short));
Add(Format.R16G16B16X16Uint, new FormatInfo(4, false, false, All.Rgb16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort));
Add(Format.R16G16B16X16Sint, new FormatInfo(4, false, false, All.Rgb16i, PixelFormat.RgbaInteger, PixelType.Short));
Add(Format.R32G32B32X32Float, new FormatInfo(4, false, false, All.Rgb32f, PixelFormat.Rgba, PixelType.Float));
Add(Format.R32G32B32X32Uint, new FormatInfo(4, false, false, All.Rgb32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt));
Add(Format.R32G32B32X32Sint, new FormatInfo(4, false, false, All.Rgb32i, PixelFormat.RgbaInteger, PixelType.Int));
Add(Format.Astc4x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc4X4Khr)); Add(Format.Astc4x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc4X4Khr));
Add(Format.Astc5x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X4Khr)); Add(Format.Astc5x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X4Khr));
Add(Format.Astc5x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X5Khr)); Add(Format.Astc5x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X5Khr));
@@ -165,12 +152,9 @@ namespace Ryujinx.Graphics.OpenGL
Add(Format.Astc12x10Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X10Khr)); Add(Format.Astc12x10Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X10Khr));
Add(Format.Astc12x12Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X12Khr)); Add(Format.Astc12x12Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X12Khr));
Add(Format.B5G6R5Unorm, new FormatInfo(3, true, false, All.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed)); Add(Format.B5G6R5Unorm, new FormatInfo(3, true, false, All.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed));
Add(Format.B5G5R5X1Unorm, new FormatInfo(4, true, false, All.Rgb5, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed));
Add(Format.B5G5R5A1Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed)); Add(Format.B5G5R5A1Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed));
Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551)); Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551));
Add(Format.B8G8R8X8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte)); Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.B8G8R8X8Srgb, new FormatInfo(4, false, false, All.Srgb8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte)); Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
Add(Format.R8Unorm, SizedInternalFormat.R8); Add(Format.R8Unorm, SizedInternalFormat.R8);

View File

@@ -236,7 +236,7 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
PreDraw(); PreDraw(vertexCount);
if (_primitiveType == PrimitiveType.Quads && !HwCapabilities.SupportsQuads) if (_primitiveType == PrimitiveType.Quads && !HwCapabilities.SupportsQuads)
{ {
@@ -354,7 +354,7 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
PreDraw(); PreDrawVbUnbounded();
int indexElemSize = 1; int indexElemSize = 1;
@@ -686,7 +686,7 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
PreDraw(); PreDrawVbUnbounded();
GL.BindBuffer((BufferTarget)All.DrawIndirectBuffer, indirectBuffer.Handle.ToInt32()); GL.BindBuffer((BufferTarget)All.DrawIndirectBuffer, indirectBuffer.Handle.ToInt32());
GL.BindBuffer((BufferTarget)All.ParameterBuffer, parameterBuffer.Handle.ToInt32()); GL.BindBuffer((BufferTarget)All.ParameterBuffer, parameterBuffer.Handle.ToInt32());
@@ -709,7 +709,7 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
PreDraw(); PreDrawVbUnbounded();
_vertexArray.SetRangeOfIndexBuffer(); _vertexArray.SetRangeOfIndexBuffer();
@@ -1515,11 +1515,22 @@ namespace Ryujinx.Graphics.OpenGL
_supportBuffer.Commit(); _supportBuffer.Commit();
} }
private void PreDraw(int vertexCount)
{
_vertexArray.PreDraw(vertexCount);
PreDraw();
}
private void PreDrawVbUnbounded()
{
_vertexArray.PreDrawVbUnbounded();
PreDraw();
}
private void PreDraw() private void PreDraw()
{ {
DrawCount++; DrawCount++;
_vertexArray.Validate();
_unit0Texture?.Bind(0); _unit0Texture?.Bind(0);
_supportBuffer.Commit(); _supportBuffer.Commit();
} }

View File

@@ -1,6 +1,7 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using System; using System;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
@@ -16,12 +17,16 @@ namespace Ryujinx.Graphics.OpenGL
private int _vertexAttribsCount; private int _vertexAttribsCount;
private int _vertexBuffersCount; private int _vertexBuffersCount;
private int _minVertexCount;
private uint _vertexAttribsInUse; private uint _vertexAttribsInUse;
private uint _vertexBuffersInUse; private uint _vertexBuffersInUse;
private uint _vertexBuffersLimited;
private BufferRange _indexBuffer; private BufferRange _indexBuffer;
private BufferHandle _tempIndexBuffer; private BufferHandle _tempIndexBuffer;
private BufferHandle _tempVertexBuffer;
private int _tempVertexBufferSize;
public VertexArray() public VertexArray()
{ {
@@ -40,6 +45,8 @@ namespace Ryujinx.Graphics.OpenGL
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers) public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
{ {
int minVertexCount = int.MaxValue;
int bindingIndex; int bindingIndex;
for (bindingIndex = 0; bindingIndex < vertexBuffers.Length; bindingIndex++) for (bindingIndex = 0; bindingIndex < vertexBuffers.Length; bindingIndex++)
{ {
@@ -47,6 +54,12 @@ namespace Ryujinx.Graphics.OpenGL
if (vb.Buffer.Handle != BufferHandle.Null) if (vb.Buffer.Handle != BufferHandle.Null)
{ {
int vertexCount = vb.Stride <= 0 ? 0 : vb.Buffer.Size / vb.Stride;
if (minVertexCount > vertexCount)
{
minVertexCount = vertexCount;
}
GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride); GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
GL.VertexBindingDivisor(bindingIndex, vb.Divisor); GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
_vertexBuffersInUse |= 1u << bindingIndex; _vertexBuffersInUse |= 1u << bindingIndex;
@@ -64,6 +77,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
_vertexBuffersCount = bindingIndex; _vertexBuffersCount = bindingIndex;
_minVertexCount = minVertexCount;
_needsAttribsUpdate = true; _needsAttribsUpdate = true;
} }
@@ -143,6 +157,101 @@ namespace Ryujinx.Graphics.OpenGL
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.Handle.ToInt32()); GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.Handle.ToInt32());
} }
public void PreDraw(int vertexCount)
{
LimitVertexBuffers(vertexCount);
Validate();
}
public void PreDrawVbUnbounded()
{
UnlimitVertexBuffers();
Validate();
}
public void LimitVertexBuffers(int vertexCount)
{
// Is it possible for the draw to fetch outside the bounds of any vertex buffer currently bound?
if (vertexCount <= _minVertexCount)
{
return;
}
// If the draw can fetch out of bounds, let's ensure that it will only fetch zeros rather than memory garbage.
int currentTempVbOffset = 0;
uint buffersInUse = _vertexBuffersInUse;
while (buffersInUse != 0)
{
int vbIndex = BitOperations.TrailingZeroCount(buffersInUse);
ref var vb = ref _vertexBuffers[vbIndex];
int requiredSize = vertexCount * vb.Stride;
if (vb.Buffer.Size < requiredSize)
{
BufferHandle tempVertexBuffer = EnsureTempVertexBufferSize(currentTempVbOffset + requiredSize);
Buffer.Copy(vb.Buffer.Handle, tempVertexBuffer, vb.Buffer.Offset, currentTempVbOffset, vb.Buffer.Size);
Buffer.Clear(tempVertexBuffer, currentTempVbOffset + vb.Buffer.Size, requiredSize - vb.Buffer.Size, 0);
GL.BindVertexBuffer(vbIndex, tempVertexBuffer.ToInt32(), (IntPtr)currentTempVbOffset, vb.Stride);
currentTempVbOffset += requiredSize;
_vertexBuffersLimited |= 1u << vbIndex;
}
buffersInUse &= ~(1u << vbIndex);
}
}
private BufferHandle EnsureTempVertexBufferSize(int size)
{
BufferHandle tempVertexBuffer = _tempVertexBuffer;
if (_tempVertexBufferSize < size)
{
_tempVertexBufferSize = size;
if (tempVertexBuffer == BufferHandle.Null)
{
tempVertexBuffer = Buffer.Create(size);
_tempVertexBuffer = tempVertexBuffer;
return tempVertexBuffer;
}
Buffer.Resize(_tempVertexBuffer, size);
}
return tempVertexBuffer;
}
public void UnlimitVertexBuffers()
{
uint buffersLimited = _vertexBuffersLimited;
if (buffersLimited == 0)
{
return;
}
while (buffersLimited != 0)
{
int vbIndex = BitOperations.TrailingZeroCount(buffersLimited);
ref var vb = ref _vertexBuffers[vbIndex];
GL.BindVertexBuffer(vbIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
buffersLimited &= ~(1u << vbIndex);
}
_vertexBuffersLimited = 0;
}
public void Validate() public void Validate()
{ {
for (int attribIndex = 0; attribIndex < _vertexAttribsCount; attribIndex++) for (int attribIndex = 0; attribIndex < _vertexAttribsCount; attribIndex++)

View File

@@ -1,19 +0,0 @@
using Ryujinx.Graphics.GAL;
namespace Ryujinx.Graphics.OpenGL
{
struct VertexBuffer
{
public BufferRange Range { get; }
public int Divisor { get; }
public int Stride { get; }
public VertexBuffer(BufferRange range, int divisor, int stride)
{
Range = range;
Divisor = divisor;
Stride = stride;
}
}
}

View File

@@ -66,7 +66,6 @@ namespace Ryujinx.Graphics.Vulkan
Add(Format.D32Float, VkFormat.D32Sfloat); Add(Format.D32Float, VkFormat.D32Sfloat);
Add(Format.D24UnormS8Uint, VkFormat.D24UnormS8Uint); Add(Format.D24UnormS8Uint, VkFormat.D24UnormS8Uint);
Add(Format.D32FloatS8Uint, VkFormat.D32SfloatS8Uint); Add(Format.D32FloatS8Uint, VkFormat.D32SfloatS8Uint);
Add(Format.R8G8B8X8Srgb, VkFormat.R8G8B8Srgb);
Add(Format.R8G8B8A8Srgb, VkFormat.R8G8B8A8Srgb); Add(Format.R8G8B8A8Srgb, VkFormat.R8G8B8A8Srgb);
Add(Format.R4G4Unorm, VkFormat.R4G4UnormPack8); Add(Format.R4G4Unorm, VkFormat.R4G4UnormPack8);
Add(Format.R4G4B4A4Unorm, VkFormat.R4G4B4A4UnormPack16); Add(Format.R4G4B4A4Unorm, VkFormat.R4G4B4A4UnormPack16);
@@ -119,18 +118,6 @@ namespace Ryujinx.Graphics.Vulkan
Add(Format.R10G10B10A2Sint, VkFormat.A2B10G10R10SintPack32); Add(Format.R10G10B10A2Sint, VkFormat.A2B10G10R10SintPack32);
Add(Format.R10G10B10A2Uscaled, VkFormat.A2B10G10R10UscaledPack32); Add(Format.R10G10B10A2Uscaled, VkFormat.A2B10G10R10UscaledPack32);
Add(Format.R10G10B10A2Sscaled, VkFormat.A2B10G10R10SscaledPack32); Add(Format.R10G10B10A2Sscaled, VkFormat.A2B10G10R10SscaledPack32);
Add(Format.R8G8B8X8Unorm, VkFormat.R8G8B8Unorm);
Add(Format.R8G8B8X8Snorm, VkFormat.R8G8B8SNorm);
Add(Format.R8G8B8X8Uint, VkFormat.R8G8B8Uint);
Add(Format.R8G8B8X8Sint, VkFormat.R8G8B8Sint);
Add(Format.R16G16B16X16Float, VkFormat.R16G16B16Sfloat);
Add(Format.R16G16B16X16Unorm, VkFormat.R16G16B16Unorm);
Add(Format.R16G16B16X16Snorm, VkFormat.R16G16B16SNorm);
Add(Format.R16G16B16X16Uint, VkFormat.R16G16B16Uint);
Add(Format.R16G16B16X16Sint, VkFormat.R16G16B16Sint);
Add(Format.R32G32B32X32Float, VkFormat.R32G32B32Sfloat);
Add(Format.R32G32B32X32Uint, VkFormat.R32G32B32Uint);
Add(Format.R32G32B32X32Sint, VkFormat.R32G32B32Sint);
Add(Format.Astc4x4Unorm, VkFormat.Astc4x4UnormBlock); Add(Format.Astc4x4Unorm, VkFormat.Astc4x4UnormBlock);
Add(Format.Astc5x4Unorm, VkFormat.Astc5x4UnormBlock); Add(Format.Astc5x4Unorm, VkFormat.Astc5x4UnormBlock);
Add(Format.Astc5x5Unorm, VkFormat.Astc5x5UnormBlock); Add(Format.Astc5x5Unorm, VkFormat.Astc5x5UnormBlock);
@@ -160,12 +147,9 @@ namespace Ryujinx.Graphics.Vulkan
Add(Format.Astc12x10Srgb, VkFormat.Astc12x10SrgbBlock); Add(Format.Astc12x10Srgb, VkFormat.Astc12x10SrgbBlock);
Add(Format.Astc12x12Srgb, VkFormat.Astc12x12SrgbBlock); Add(Format.Astc12x12Srgb, VkFormat.Astc12x12SrgbBlock);
Add(Format.B5G6R5Unorm, VkFormat.R5G6B5UnormPack16); Add(Format.B5G6R5Unorm, VkFormat.R5G6B5UnormPack16);
Add(Format.B5G5R5X1Unorm, VkFormat.A1R5G5B5UnormPack16);
Add(Format.B5G5R5A1Unorm, VkFormat.A1R5G5B5UnormPack16); Add(Format.B5G5R5A1Unorm, VkFormat.A1R5G5B5UnormPack16);
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16); Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
Add(Format.B8G8R8X8Unorm, VkFormat.B8G8R8Unorm);
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm); Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
Add(Format.B8G8R8X8Srgb, VkFormat.B8G8R8Srgb);
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb); Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
} }

View File

@@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan
Length = length; Length = length;
} }
public Span<T> ToSpan() public Span<T> AsSpan()
{ {
return new Span<T>(Pointer, Length); return new Span<T>(Pointer, Length);
} }

View File

@@ -582,7 +582,7 @@ namespace Ryujinx.Graphics.Vulkan
_newState.PipelineLayout = internalProgram.PipelineLayout; _newState.PipelineLayout = internalProgram.PipelineLayout;
_newState.StagesCount = (uint)stages.Length; _newState.StagesCount = (uint)stages.Length;
stages.CopyTo(_newState.Stages.ToSpan().Slice(0, stages.Length)); stages.CopyTo(_newState.Stages.AsSpan().Slice(0, stages.Length));
SignalStateChange(); SignalStateChange();
} }
@@ -921,7 +921,7 @@ namespace Ryujinx.Graphics.Vulkan
protected void UpdatePipelineAttachmentFormats() protected void UpdatePipelineAttachmentFormats()
{ {
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.ToSpan(); var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats); FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex + (FramebufferParams.HasDepthStencil ? 1 : 0); int maxAttachmentIndex = FramebufferParams.MaxColorAttachmentIndex + (FramebufferParams.HasDepthStencil ? 1 : 0);

View File

@@ -117,7 +117,7 @@ namespace Ryujinx.Graphics.Vulkan
private void RecordScissor(Vk api, CommandBuffer commandBuffer) private void RecordScissor(Vk api, CommandBuffer commandBuffer)
{ {
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.ToSpan()); api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
} }
private void RecordStencilMasks(Vk api, CommandBuffer commandBuffer) private void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
@@ -132,7 +132,7 @@ namespace Ryujinx.Graphics.Vulkan
private void RecordViewport(Vk api, CommandBuffer commandBuffer) private void RecordViewport(Vk api, CommandBuffer commandBuffer)
{ {
api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, Viewports.ToSpan()); api.CmdSetViewport(commandBuffer, 0, (uint)ViewportsCount, Viewports.AsSpan());
} }
} }
} }

View File

@@ -52,22 +52,22 @@ namespace Ryujinx.Graphics.Vulkan
return false; return false;
} }
if (!SequenceEqual<VertexInputAttributeDescription>(VertexAttributeDescriptions.ToSpan(), other.VertexAttributeDescriptions.ToSpan(), VertexAttributeDescriptionsCount)) if (!SequenceEqual<VertexInputAttributeDescription>(VertexAttributeDescriptions.AsSpan(), other.VertexAttributeDescriptions.AsSpan(), VertexAttributeDescriptionsCount))
{ {
return false; return false;
} }
if (!SequenceEqual<VertexInputBindingDescription>(VertexBindingDescriptions.ToSpan(), other.VertexBindingDescriptions.ToSpan(), VertexBindingDescriptionsCount)) if (!SequenceEqual<VertexInputBindingDescription>(VertexBindingDescriptions.AsSpan(), other.VertexBindingDescriptions.AsSpan(), VertexBindingDescriptionsCount))
{ {
return false; return false;
} }
if (!SequenceEqual<PipelineColorBlendAttachmentState>(ColorBlendAttachmentState.ToSpan(), other.ColorBlendAttachmentState.ToSpan(), ColorBlendAttachmentStateCount)) if (!SequenceEqual<PipelineColorBlendAttachmentState>(ColorBlendAttachmentState.AsSpan(), other.ColorBlendAttachmentState.AsSpan(), ColorBlendAttachmentStateCount))
{ {
return false; return false;
} }
if (!SequenceEqual<Format>(AttachmentFormats.ToSpan(), other.AttachmentFormats.ToSpan(), ColorBlendAttachmentStateCount + (HasDepthStencil ? 1u : 0u))) if (!SequenceEqual<Format>(AttachmentFormats.AsSpan(), other.AttachmentFormats.AsSpan(), ColorBlendAttachmentStateCount + (HasDepthStencil ? 1u : 0u)))
{ {
return false; return false;
} }

View File

@@ -245,7 +245,7 @@ namespace Ryujinx.Graphics.Vulkan
PipelineState pipeline = _state.ToVulkanPipelineState(_gd); PipelineState pipeline = _state.ToVulkanPipelineState(_gd);
// Copy the shader stage info to the pipeline. // Copy the shader stage info to the pipeline.
var stages = pipeline.Stages.ToSpan(); var stages = pipeline.Stages.AsSpan();
for (int i = 0; i < _shaders.Length; i++) for (int i = 0; i < _shaders.Length; i++)
{ {

View File

@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
private byte element; private byte element;
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref element, 8 * 0x81); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref element, 8 * 0x81);
} }
} }
#pragma warning restore CS0649 #pragma warning restore CS0649

View File

@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Applets
{ {
private byte element; private byte element;
public Span<byte> ToSpan() => MemoryMarshal.CreateSpan(ref element, 4 * 0x81); public Span<byte> AsSpan() => MemoryMarshal.CreateSpan(ref element, 4 * 0x81);
} }
} }
#pragma warning restore CS0649 #pragma warning restore CS0649

View File

@@ -179,8 +179,8 @@ namespace Ryujinx.HLE.HOS.Applets.Error
byte[] messageTextBuffer = new byte[0x800]; byte[] messageTextBuffer = new byte[0x800];
byte[] detailsTextBuffer = new byte[0x800]; byte[] detailsTextBuffer = new byte[0x800];
applicationErrorArg.MessageText.ToSpan().CopyTo(messageTextBuffer); applicationErrorArg.MessageText.AsSpan().CopyTo(messageTextBuffer);
applicationErrorArg.DetailsText.ToSpan().CopyTo(detailsTextBuffer); applicationErrorArg.DetailsText.AsSpan().CopyTo(detailsTextBuffer);
string messageText = Encoding.ASCII.GetString(messageTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray()); string messageText = Encoding.ASCII.GetString(messageTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());
string detailsText = Encoding.ASCII.GetString(detailsTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray()); string detailsText = Encoding.ASCII.GetString(detailsTextBuffer.TakeWhile(b => !b.Equals(0)).ToArray());

View File

@@ -117,7 +117,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio
OpusMultiStreamParametersEx parameters = context.Memory.Read<OpusMultiStreamParametersEx>(parametersAddress); OpusMultiStreamParametersEx parameters = context.Memory.Read<OpusMultiStreamParametersEx>(parametersAddress);
byte[] mappings = MemoryMarshal.Cast<uint, byte>(parameters.ChannelMappings.ToSpan()).ToArray(); byte[] mappings = MemoryMarshal.Cast<uint, byte>(parameters.ChannelMappings.AsSpan()).ToArray();
// UseLargeFrameSize can be ignored due to not relying on fixed size buffers for storing the decoded result. // UseLargeFrameSize can be ignored due to not relying on fixed size buffers for storing the decoded result.
MakeObject(context, new IHardwareOpusDecoder( MakeObject(context, new IHardwareOpusDecoder(

View File

@@ -277,7 +277,7 @@ namespace Ryujinx.HLE.HOS.Services.Friend.ServiceCreator
Array16<byte> randomGuid = new Array16<byte>(); Array16<byte> randomGuid = new Array16<byte>();
Guid.NewGuid().ToByteArray().AsSpan().CopyTo(randomGuid.ToSpan()); Guid.NewGuid().ToByteArray().AsSpan().CopyTo(randomGuid.AsSpan());
PlayHistoryRegistrationKey playHistoryRegistrationKey = new PlayHistoryRegistrationKey PlayHistoryRegistrationKey playHistoryRegistrationKey = new PlayHistoryRegistrationKey
{ {

View File

@@ -26,7 +26,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
SamplingNumber = previousEntry.SamplingNumber + 1, SamplingNumber = previousEntry.SamplingNumber + 1,
}; };
keyState.Keys.AsSpan().CopyTo(newState.Keys.RawData.ToSpan()); keyState.Keys.AsSpan().CopyTo(newState.Keys.RawData.AsSpan());
newState.Modifiers = (KeyboardModifier)keyState.Modifier; newState.Modifiers = (KeyboardModifier)keyState.Modifier;
lifo.Write(ref newState); lifo.Write(ref newState);

View File

@@ -543,7 +543,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
Attributes = SixAxisSensorAttribute.IsConnected Attributes = SixAxisSensorAttribute.IsConnected
}; };
state.Orientation.AsSpan().CopyTo(newState.Direction.ToSpan()); state.Orientation.AsSpan().CopyTo(newState.Direction.AsSpan());
ref RingLifo<SixAxisSensorState> lifo = ref GetSixAxisSensorLifo(ref currentNpad, isRightPair); ref RingLifo<SixAxisSensorState> lifo = ref GetSixAxisSensorLifo(ref currentNpad, isRightPair);

View File

@@ -628,7 +628,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
Reserved2 = new Array6<byte>() Reserved2 = new Array6<byte>()
}; };
Uuid.CopyTo(tagInfo.Uuid.ToSpan()); Uuid.CopyTo(tagInfo.Uuid.AsSpan());
context.Memory.Write(outputPosition, tagInfo); context.Memory.Write(outputPosition, tagInfo);

View File

@@ -85,7 +85,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
Reserved1 = new Array64<byte>(), Reserved1 = new Array64<byte>(),
Reserved2 = new Array58<byte>() Reserved2 = new Array58<byte>()
}; };
Encoding.ASCII.GetBytes("Ryujinx").CopyTo(registerInfo.Nickname.ToSpan()); Encoding.ASCII.GetBytes("Ryujinx").CopyTo(registerInfo.Nickname.AsSpan());
return registerInfo; return registerInfo;
} }

View File

@@ -84,7 +84,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress); networkProfile.IpSettingData.IpAddressSetting = new IpAddressSetting(interfaceProperties, unicastAddress);
networkProfile.IpSettingData.DnsSetting = new DnsSetting(interfaceProperties); networkProfile.IpSettingData.DnsSetting = new DnsSetting(interfaceProperties);
Encoding.ASCII.GetBytes("RyujinxNetwork").CopyTo(networkProfile.Name.ToSpan()); Encoding.ASCII.GetBytes("RyujinxNetwork").CopyTo(networkProfile.Name.AsSpan());
context.Memory.Write(networkProfileDataPosition, networkProfile); context.Memory.Write(networkProfileDataPosition, networkProfile);

View File

@@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
public IPEndPoint ToIPEndPoint() public IPEndPoint ToIPEndPoint()
{ {
IPAddress address = new IPAddress(Address.ToSpan()); IPAddress address = new IPAddress(Address.AsSpan());
int port = (ushort)IPAddress.NetworkToHostOrder((short)Port); int port = (ushort)IPAddress.NetworkToHostOrder((short)Port);
return new IPEndPoint(address, port); return new IPEndPoint(address, port);
@@ -31,7 +31,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
Port = (ushort)IPAddress.HostToNetworkOrder((short)endpoint.Port) Port = (ushort)IPAddress.HostToNetworkOrder((short)endpoint.Port)
}; };
endpoint.Address.GetAddressBytes().AsSpan().CopyTo(result.Address.ToSpan()); endpoint.Address.GetAddressBytes().AsSpan().CopyTo(result.Address.AsSpan());
return result; return result;
} }

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
Port = port; Port = port;
Address = new Array4<byte>(); Address = new Array4<byte>();
address.TryWriteBytes(Address.ToSpan(), out _); address.TryWriteBytes(Address.AsSpan(), out _);
} }
public void ToNetworkOrder() public void ToNetworkOrder()
@@ -43,7 +43,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
{ {
if (BitConverter.IsLittleEndian) if (BitConverter.IsLittleEndian)
{ {
address.ToSpan().Reverse(); address.AsSpan().Reverse();
} }
} }
} }

View File

@@ -1440,7 +1440,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
int timeZoneSize = Math.Min(StringUtils.LengthCstr(timeZoneAbbreviation), 8); int timeZoneSize = Math.Min(StringUtils.LengthCstr(timeZoneAbbreviation), 8);
timeZoneAbbreviation[..timeZoneSize].CopyTo(calendarAdditionalInfo.TimezoneName.ToSpan()); timeZoneAbbreviation[..timeZoneSize].CopyTo(calendarAdditionalInfo.TimezoneName.AsSpan());
} }
return result; return result;

View File

@@ -49,7 +49,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
Height = height Height = height
}; };
Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(displayInfo.Name.ToSpan()); Encoding.ASCII.GetBytes(name).AsSpan().CopyTo(displayInfo.Name.AsSpan());
_displayInfo.Add(displayInfo); _displayInfo.Add(displayInfo);
} }
@@ -171,7 +171,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
return ResultCode.InvalidValue; return ResultCode.InvalidValue;
} }
int displayId = _displayInfo.FindIndex(display => Encoding.ASCII.GetString(display.Name.ToSpan()).Trim('\0') == name); int displayId = _displayInfo.FindIndex(display => Encoding.ASCII.GetString(display.Name.AsSpan()).Trim('\0') == name);
if (displayId == -1) if (displayId == -1)
{ {

View File

@@ -46,7 +46,7 @@ namespace Spv.Generator
result += _resultType.WordCount; result += _resultType.WordCount;
} }
Span<Operand> operands = _operands.ToSpan(); Span<Operand> operands = _operands.AsSpan();
for (int i = 0; i < operands.Length; i++) for (int i = 0; i < operands.Length; i++)
{ {
result += operands[i].WordCount; result += operands[i].WordCount;
@@ -120,7 +120,7 @@ namespace Spv.Generator
writer.Write(Id); writer.Write(Id);
} }
Span<Operand> operands = _operands.ToSpan(); Span<Operand> operands = _operands.AsSpan();
for (int i = 0; i < operands.Length; i++) for (int i = 0; i < operands.Length; i++)
{ {
operands[i].WriteOperand(writer); operands[i].WriteOperand(writer);
@@ -185,8 +185,8 @@ namespace Spv.Generator
public bool EqualsContent(Instruction cmpObj) public bool EqualsContent(Instruction cmpObj)
{ {
Span<Operand> thisOperands = _operands.ToSpan(); Span<Operand> thisOperands = _operands.AsSpan();
Span<Operand> cmpOperands = cmpObj._operands.ToSpan(); Span<Operand> cmpOperands = cmpObj._operands.AsSpan();
if (thisOperands.Length != cmpOperands.Length) if (thisOperands.Length != cmpOperands.Length)
{ {
@@ -211,7 +211,7 @@ namespace Spv.Generator
public int GetHashCodeContent() public int GetHashCodeContent()
{ {
return DeterministicHashCode.Combine<Operand>(_operands.ToSpan()); return DeterministicHashCode.Combine<Operand>(_operands.AsSpan());
} }
public int GetHashCodeResultType() public int GetHashCodeResultType()
@@ -221,7 +221,7 @@ namespace Spv.Generator
public override int GetHashCode() public override int GetHashCode()
{ {
return DeterministicHashCode.Combine(Opcode, Id, _resultType, DeterministicHashCode.Combine<Operand>(_operands.ToSpan())); return DeterministicHashCode.Combine(Opcode, Id, _resultType, DeterministicHashCode.Combine<Operand>(_operands.AsSpan()));
} }
public bool Equals(Operand obj) public bool Equals(Operand obj)

View File

@@ -15,7 +15,7 @@ namespace Spv.Generator
public Operand Operand5; public Operand Operand5;
public Operand[] Overflow; public Operand[] Overflow;
public Span<Operand> ToSpan() public Span<Operand> AsSpan()
{ {
if (Count > InternalCount) if (Count > InternalCount)
{ {