diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-03-16 00:42:44 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-03-16 00:42:44 -0300 |
| commit | 4940cf0ea58c77c8666d76abdfc35c6380efed4c (patch) | |
| tree | 63f3a364c0259435c6a32d362eacf5590231d115 | |
| parent | 88c6160c62b000d155a829b23e6207d78b7dccfa (diff) | |
Add BFI instruction, even more audout fixes
| -rw-r--r-- | ChocolArm64/AOpCodeTable.cs | 1 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdLogical.cs | 30 | ||||
| -rw-r--r-- | Ryujinx.Audio/IAalOutput.cs | 6 | ||||
| -rw-r--r-- | Ryujinx.Audio/OpenAL/OpenALAudioOut.cs | 109 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs | 2 |
5 files changed, 97 insertions, 51 deletions
diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index 9240c0a7..c28abe5c 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -139,6 +139,7 @@ namespace ChocolArm64 Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg)); Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg)); Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm)); + Set("0x101110111xxxxx000111xxxxxxxxxx", AInstEmit.Bif_V, typeof(AOpCodeSimdReg)); Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg)); Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd)); diff --git a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs index 5b71a0bb..8fd8ea4d 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdLogical.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdLogical.cs @@ -32,6 +32,36 @@ namespace ChocolArm64.Instruction }); } + public static void Bif_V(AILEmitterCtx Context) + { + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; + + int Bytes = Context.CurrOp.GetBitsCount() >> 3; + + for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + { + EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size); + EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); + + Context.Emit(OpCodes.Xor); + + EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size); + + Context.Emit(OpCodes.And); + + EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size); + + Context.Emit(OpCodes.Xor); + + EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } + public static void Bsl_V(AILEmitterCtx Context) { EmitVectorTernaryOpZx(Context, () => diff --git a/Ryujinx.Audio/IAalOutput.cs b/Ryujinx.Audio/IAalOutput.cs index 7ed0e0b6..5ffeebdd 100644 --- a/Ryujinx.Audio/IAalOutput.cs +++ b/Ryujinx.Audio/IAalOutput.cs @@ -3,12 +3,14 @@ namespace Ryujinx.Audio public interface IAalOutput { int OpenTrack(int SampleRate, int Channels, out AudioFormat Format); + void CloseTrack(int Track); - void AppendBuffer(int Track, long Tag, byte[] Buffer); bool ContainsBuffer(int Track, long Tag); - long[] GetReleasedBuffers(int Track); + long[] GetReleasedBuffers(int Track, int MaxCount); + + void AppendBuffer(int Track, long Tag, byte[] Buffer); void Start(int Track); void Stop(int Track); diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs index 7cf30c18..48dcd199 100644 --- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs +++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs @@ -10,6 +10,8 @@ namespace Ryujinx.Audio.OpenAL { private const int MaxTracks = 256; + private const int MaxReleased = 32; + private AudioContext Context; private class Track : IDisposable @@ -26,6 +28,8 @@ namespace Ryujinx.Audio.OpenAL private Queue<long> QueuedTagsQueue; + private Queue<long> ReleasedTagsQueue; + private bool Disposed; public Track(int SampleRate, ALFormat Format) @@ -40,38 +44,36 @@ namespace Ryujinx.Audio.OpenAL Buffers = new ConcurrentDictionary<long, int>(); QueuedTagsQueue = new Queue<long>(); + + ReleasedTagsQueue = new Queue<long>(); } - public int GetBufferId(long Tag) + public bool ContainsBuffer(long Tag) { - if (Disposed) - { - throw new ObjectDisposedException(nameof(Track)); - } - - int Id = AL.GenBuffer(); + SyncQueuedTags(); - Buffers.AddOrUpdate(Tag, Id, (Key, OldId) => + foreach (long QueuedTag in QueuedTagsQueue) { - AL.DeleteBuffer(OldId); - - return Id; - }); - - QueuedTagsQueue.Enqueue(Tag); + if (QueuedTag == Tag) + { + return true; + } + } - return Id; + return false; } - public long[] GetReleasedBuffers() + public long[] GetReleasedBuffers(int MaxCount) { ClearReleased(); List<long> Tags = new List<long>(); - foreach (long Tag in Buffers.Keys) + HashSet<long> Unique = new HashSet<long>(); + + while (MaxCount-- > 0 && ReleasedTagsQueue.TryDequeue(out long Tag)) { - if (!ContainsBuffer(Tag)) + if (Unique.Add(Tag)) { Tags.Add(Tag); } @@ -80,31 +82,37 @@ namespace Ryujinx.Audio.OpenAL return Tags.ToArray(); } - public void ClearReleased() + public int AppendBuffer(long Tag) { - SyncQueuedTags(); + if (Disposed) + { + throw new ObjectDisposedException(nameof(Track)); + } - AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + int Id = AL.GenBuffer(); - if (ReleasedCount > 0) + Buffers.AddOrUpdate(Tag, Id, (Key, OldId) => { - AL.SourceUnqueueBuffers(SourceId, ReleasedCount); - } + AL.DeleteBuffer(OldId); + + return Id; + }); + + QueuedTagsQueue.Enqueue(Tag); + + return Id; } - public bool ContainsBuffer(long Tag) + public void ClearReleased() { SyncQueuedTags(); - foreach (long QueuedTag in QueuedTagsQueue) + AL.GetSource(SourceId, ALGetSourcei.BuffersProcessed, out int ReleasedCount); + + if (ReleasedCount > 0) { - if (QueuedTag == Tag) - { - return true; - } + AL.SourceUnqueueBuffers(SourceId, ReleasedCount); } - - return false; } private void SyncQueuedTags() @@ -116,7 +124,12 @@ namespace Ryujinx.Audio.OpenAL while (QueuedTagsQueue.Count > QueuedCount) { - QueuedTagsQueue.Dequeue(); + ReleasedTagsQueue.Enqueue(QueuedTagsQueue.Dequeue()); + } + + while (ReleasedTagsQueue.Count > MaxReleased) + { + ReleasedTagsQueue.Dequeue(); } } @@ -202,38 +215,38 @@ namespace Ryujinx.Audio.OpenAL } } - public void AppendBuffer(int Track, long Tag, byte[] Buffer) + public bool ContainsBuffer(int Track, long Tag) { if (Tracks.TryGetValue(Track, out Track Td)) { - int BufferId = Td.GetBufferId(Tag); - - AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate); - - AL.SourceQueueBuffer(Td.SourceId, BufferId); - - StartPlaybackIfNeeded(Td); + return Td.ContainsBuffer(Tag); } + + return false; } - public bool ContainsBuffer(int Track, long Tag) + public long[] GetReleasedBuffers(int Track, int MaxCount) { if (Tracks.TryGetValue(Track, out Track Td)) { - return Td.ContainsBuffer(Tag); + return Td.GetReleasedBuffers(MaxCount); } - return false; + return null; } - public long[] GetReleasedBuffers(int Track) + public void AppendBuffer(int Track, long Tag, byte[] Buffer) { if (Tracks.TryGetValue(Track, out Track Td)) { - return Td.GetReleasedBuffers(); + int BufferId = Td.AppendBuffer(Tag); + + AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate); + + AL.SourceQueueBuffer(Td.SourceId, BufferId); + + StartPlaybackIfNeeded(Td); } - - return null; } public void Start(int Track) diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs index d0528a6d..8cd013f8 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs @@ -91,7 +91,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud uint Count = (uint)((ulong)Size >> 3); - long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track); + long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track, (int)Count); for (uint Index = 0; Index < Count; Index++) { |
