Bläddra i källkod

Add BFI instruction, even more audout fixes

gdkchan 8 år sedan
förälder
incheckning
4940cf0ea5

+ 1 - 0
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));

+ 30 - 0
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, () =>

+ 4 - 2
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);

+ 61 - 48
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)

+ 1 - 1
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++)
             {