1
0
Fork 0
mirror of https://github.com/Ryujinx/Ryujinx.git synced 2024-11-23 22:32:08 +00:00

Add BFI instruction, even more audout fixes

This commit is contained in:
gdkchan 2018-03-16 00:42:44 -03:00
parent 88c6160c62
commit 4940cf0ea5
5 changed files with 99 additions and 53 deletions

View file

@ -139,6 +139,7 @@ namespace ChocolArm64
Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg)); Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg));
Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg)); Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg));
Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm)); Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm));
Set("0x101110111xxxxx000111xxxxxxxxxx", AInstEmit.Bif_V, typeof(AOpCodeSimdReg));
Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg)); Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd)); Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));

View file

@ -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) public static void Bsl_V(AILEmitterCtx Context)
{ {
EmitVectorTernaryOpZx(Context, () => EmitVectorTernaryOpZx(Context, () =>

View file

@ -3,12 +3,14 @@ namespace Ryujinx.Audio
public interface IAalOutput public interface IAalOutput
{ {
int OpenTrack(int SampleRate, int Channels, out AudioFormat Format); int OpenTrack(int SampleRate, int Channels, out AudioFormat Format);
void CloseTrack(int Track); void CloseTrack(int Track);
void AppendBuffer(int Track, long Tag, byte[] Buffer);
bool ContainsBuffer(int Track, long Tag); 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 Start(int Track);
void Stop(int Track); void Stop(int Track);

View file

@ -10,6 +10,8 @@ namespace Ryujinx.Audio.OpenAL
{ {
private const int MaxTracks = 256; private const int MaxTracks = 256;
private const int MaxReleased = 32;
private AudioContext Context; private AudioContext Context;
private class Track : IDisposable private class Track : IDisposable
@ -26,6 +28,8 @@ namespace Ryujinx.Audio.OpenAL
private Queue<long> QueuedTagsQueue; private Queue<long> QueuedTagsQueue;
private Queue<long> ReleasedTagsQueue;
private bool Disposed; private bool Disposed;
public Track(int SampleRate, ALFormat Format) public Track(int SampleRate, ALFormat Format)
@ -40,9 +44,45 @@ namespace Ryujinx.Audio.OpenAL
Buffers = new ConcurrentDictionary<long, int>(); Buffers = new ConcurrentDictionary<long, int>();
QueuedTagsQueue = new Queue<long>(); QueuedTagsQueue = new Queue<long>();
ReleasedTagsQueue = new Queue<long>();
} }
public int GetBufferId(long Tag) public bool ContainsBuffer(long Tag)
{
SyncQueuedTags();
foreach (long QueuedTag in QueuedTagsQueue)
{
if (QueuedTag == Tag)
{
return true;
}
}
return false;
}
public long[] GetReleasedBuffers(int MaxCount)
{
ClearReleased();
List<long> Tags = new List<long>();
HashSet<long> Unique = new HashSet<long>();
while (MaxCount-- > 0 && ReleasedTagsQueue.TryDequeue(out long Tag))
{
if (Unique.Add(Tag))
{
Tags.Add(Tag);
}
}
return Tags.ToArray();
}
public int AppendBuffer(long Tag)
{ {
if (Disposed) if (Disposed)
{ {
@ -63,23 +103,6 @@ namespace Ryujinx.Audio.OpenAL
return Id; return Id;
} }
public long[] GetReleasedBuffers()
{
ClearReleased();
List<long> Tags = new List<long>();
foreach (long Tag in Buffers.Keys)
{
if (!ContainsBuffer(Tag))
{
Tags.Add(Tag);
}
}
return Tags.ToArray();
}
public void ClearReleased() public void ClearReleased()
{ {
SyncQueuedTags(); SyncQueuedTags();
@ -92,21 +115,6 @@ namespace Ryujinx.Audio.OpenAL
} }
} }
public bool ContainsBuffer(long Tag)
{
SyncQueuedTags();
foreach (long QueuedTag in QueuedTagsQueue)
{
if (QueuedTag == Tag)
{
return true;
}
}
return false;
}
private void SyncQueuedTags() private void SyncQueuedTags()
{ {
AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount); AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount);
@ -116,7 +124,12 @@ namespace Ryujinx.Audio.OpenAL
while (QueuedTagsQueue.Count > QueuedCount) while (QueuedTagsQueue.Count > QueuedCount)
{ {
QueuedTagsQueue.Dequeue(); ReleasedTagsQueue.Enqueue(QueuedTagsQueue.Dequeue());
}
while (ReleasedTagsQueue.Count > MaxReleased)
{
ReleasedTagsQueue.Dequeue();
} }
} }
@ -202,20 +215,6 @@ namespace Ryujinx.Audio.OpenAL
} }
} }
public void AppendBuffer(int Track, long Tag, byte[] Buffer)
{
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);
}
}
public bool ContainsBuffer(int Track, long Tag) public bool ContainsBuffer(int Track, long Tag)
{ {
if (Tracks.TryGetValue(Track, out Track Td)) if (Tracks.TryGetValue(Track, out Track Td))
@ -226,16 +225,30 @@ namespace Ryujinx.Audio.OpenAL
return false; return false;
} }
public long[] GetReleasedBuffers(int Track) public long[] GetReleasedBuffers(int Track, int MaxCount)
{ {
if (Tracks.TryGetValue(Track, out Track Td)) if (Tracks.TryGetValue(Track, out Track Td))
{ {
return Td.GetReleasedBuffers(); return Td.GetReleasedBuffers(MaxCount);
} }
return null; return null;
} }
public void AppendBuffer(int Track, long Tag, byte[] Buffer)
{
if (Tracks.TryGetValue(Track, out Track Td))
{
int BufferId = Td.AppendBuffer(Tag);
AL.BufferData(BufferId, Td.Format, Buffer, Buffer.Length, Td.SampleRate);
AL.SourceQueueBuffer(Td.SourceId, BufferId);
StartPlaybackIfNeeded(Td);
}
}
public void Start(int Track) public void Start(int Track)
{ {
if (Tracks.TryGetValue(Track, out Track Td)) if (Tracks.TryGetValue(Track, out Track Td))

View file

@ -91,7 +91,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Aud
uint Count = (uint)((ulong)Size >> 3); 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++) for (uint Index = 0; Index < Count; Index++)
{ {