mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-11-24 11:54:15 +00:00
Add BFI instruction, even more audout fixes
This commit is contained in:
parent
88c6160c62
commit
4940cf0ea5
5 changed files with 99 additions and 53 deletions
|
@ -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));
|
||||||
|
|
|
@ -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, () =>
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue