aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-03-16 00:42:44 -0300
committergdkchan <gab.dark.100@gmail.com>2018-03-16 00:42:44 -0300
commit4940cf0ea58c77c8666d76abdfc35c6380efed4c (patch)
tree63f3a364c0259435c6a32d362eacf5590231d115
parent88c6160c62b000d155a829b23e6207d78b7dccfa (diff)
Add BFI instruction, even more audout fixes
-rw-r--r--ChocolArm64/AOpCodeTable.cs1
-rw-r--r--ChocolArm64/Instruction/AInstEmitSimdLogical.cs30
-rw-r--r--Ryujinx.Audio/IAalOutput.cs6
-rw-r--r--Ryujinx.Audio/OpenAL/OpenALAudioOut.cs109
-rw-r--r--Ryujinx.Core/OsHle/Services/Aud/IAudioOut.cs2
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++)
{