Merge branch 'master' into patch-3

This commit is contained in:
greggameplayer 2018-07-10 23:24:11 +02:00 committed by GitHub
commit 1f8206c12b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 156 additions and 34 deletions

View file

@ -339,9 +339,12 @@ namespace ChocolArm64.Instruction
EmitVectorExtractZx(Context, (Index & 1) == 0 ? Op.Rn : Op.Rm, Elem, Op.Size); EmitVectorExtractZx(Context, (Index & 1) == 0 ? Op.Rn : Op.Rm, Elem, Op.Size);
EmitVectorInsert(Context, Op.Rd, Index, Op.Size); EmitVectorInsertTmp(Context, Index, Op.Size);
} }
Context.EmitLdvectmp();
Context.EmitStvec(Op.Rd);
if (Op.RegisterSize == ARegisterSize.SIMD64) if (Op.RegisterSize == ARegisterSize.SIMD64)
{ {
EmitVectorZeroUpper(Context, Op.Rd); EmitVectorZeroUpper(Context, Op.Rd);
@ -363,9 +366,12 @@ namespace ChocolArm64.Instruction
EmitVectorExtractZx(Context, Index < Half ? Op.Rn : Op.Rm, Elem, Op.Size); EmitVectorExtractZx(Context, Index < Half ? Op.Rn : Op.Rm, Elem, Op.Size);
EmitVectorInsert(Context, Op.Rd, Index, Op.Size); EmitVectorInsertTmp(Context, Index, Op.Size);
} }
Context.EmitLdvectmp();
Context.EmitStvec(Op.Rd);
if (Op.RegisterSize == ARegisterSize.SIMD64) if (Op.RegisterSize == ARegisterSize.SIMD64)
{ {
EmitVectorZeroUpper(Context, Op.Rd); EmitVectorZeroUpper(Context, Op.Rd);
@ -387,9 +393,12 @@ namespace ChocolArm64.Instruction
EmitVectorExtractZx(Context, (Index & 1) == 0 ? Op.Rn : Op.Rm, Elem, Op.Size); EmitVectorExtractZx(Context, (Index & 1) == 0 ? Op.Rn : Op.Rm, Elem, Op.Size);
EmitVectorInsert(Context, Op.Rd, Index, Op.Size); EmitVectorInsertTmp(Context, Index, Op.Size);
} }
Context.EmitLdvectmp();
Context.EmitStvec(Op.Rd);
if (Op.RegisterSize == ARegisterSize.SIMD64) if (Op.RegisterSize == ARegisterSize.SIMD64)
{ {
EmitVectorZeroUpper(Context, Op.Rd); EmitVectorZeroUpper(Context, Op.Rd);

View file

@ -20,7 +20,7 @@ namespace Ryujinx.Audio.OpenAL
public int SourceId { get; private set; } public int SourceId { get; private set; }
public int SampleRate { get; private set; } public int SampleRate { get; private set; }
public ALFormat Format { get; private set; } public ALFormat Format { get; private set; }
private ReleaseCallback Callback; private ReleaseCallback Callback;
@ -153,7 +153,7 @@ namespace Ryujinx.Audio.OpenAL
ShouldCallReleaseCallback = true; ShouldCallReleaseCallback = true;
} }
} }
private void SyncQueuedTags() private void SyncQueuedTags()
{ {
AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount); AL.GetSource(SourceId, ALGetSourcei.BuffersQueued, out int QueuedCount);
@ -249,11 +249,6 @@ namespace Ryujinx.Audio.OpenAL
private ALFormat GetALFormat(int Channels, AudioFormat Format) private ALFormat GetALFormat(int Channels, AudioFormat Format)
{ {
if (Channels < 1 || Channels > 2)
{
throw new ArgumentOutOfRangeException(nameof(Channels));
}
if (Channels == 1) if (Channels == 1)
{ {
switch (Format) switch (Format)
@ -262,7 +257,7 @@ namespace Ryujinx.Audio.OpenAL
case AudioFormat.PcmInt16: return ALFormat.Mono16; case AudioFormat.PcmInt16: return ALFormat.Mono16;
} }
} }
else /* if (Channels == 2) */ else if (Channels == 2)
{ {
switch (Format) switch (Format)
{ {
@ -270,6 +265,18 @@ namespace Ryujinx.Audio.OpenAL
case AudioFormat.PcmInt16: return ALFormat.Stereo16; case AudioFormat.PcmInt16: return ALFormat.Stereo16;
} }
} }
else if (Channels == 6)
{
switch (Format)
{
case AudioFormat.PcmInt8: return ALFormat.Multi51Chn8Ext;
case AudioFormat.PcmInt16: return ALFormat.Multi51Chn16Ext;
}
}
else
{
throw new ArgumentOutOfRangeException(nameof(Channels));
}
throw new ArgumentException(nameof(Format)); throw new ArgumentException(nameof(Format));
} }
@ -288,7 +295,7 @@ namespace Ryujinx.Audio.OpenAL
{ {
return Td.ContainsBuffer(Tag); return Td.ContainsBuffer(Tag);
} }
return false; return false;
} }
@ -298,7 +305,7 @@ namespace Ryujinx.Audio.OpenAL
{ {
return Td.GetReleasedBuffers(MaxCount); return Td.GetReleasedBuffers(MaxCount);
} }
return null; return null;
} }

View file

@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Gal
BC3 = 0x26, BC3 = 0x26,
BC4 = 0x27, BC4 = 0x27,
BC5 = 0x28, BC5 = 0x28,
ZF32 = 0x2f,
Astc2D4x4 = 0x40, Astc2D4x4 = 0x40,
Astc2D5x5 = 0x41, Astc2D5x5 = 0x41,
Astc2D6x6 = 0x42, Astc2D6x6 = 0x42,

View file

@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal
{ {
public interface IGalRasterizer public interface IGalRasterizer
{ {
void LockCaches();
void UnlockCaches();
void ClearBuffers(GalClearBufferFlags Flags); void ClearBuffers(GalClearBufferFlags Flags);
bool IsVboCached(long Key, long DataSize); bool IsVboCached(long Key, long DataSize);
@ -46,9 +49,9 @@ namespace Ryujinx.Graphics.Gal
void CreateIbo(long Key, byte[] Buffer); void CreateIbo(long Key, byte[] Buffer);
void SetVertexArray(int VbIndex, int Stride, long VboKey, GalVertexAttrib[] Attribs); void SetVertexArray(int Stride, long VboKey, GalVertexAttrib[] Attribs);
void SetIndexArray(long Key, int Size, GalIndexFormat Format); void SetIndexArray(int Size, GalIndexFormat Format);
void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType); void DrawArrays(int First, int PrimCount, GalPrimitiveType PrimType);

View file

@ -2,6 +2,9 @@ namespace Ryujinx.Graphics.Gal
{ {
public interface IGalTexture public interface IGalTexture
{ {
void LockCache();
void UnlockCache();
void Create(long Key, byte[] Data, GalTexture Texture); void Create(long Key, byte[] Data, GalTexture Texture);
bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture); bool TryGetCachedTexture(long Key, long DataSize, out GalTexture Texture);

View file

@ -36,6 +36,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private DeleteValue DeleteValueCallback; private DeleteValue DeleteValueCallback;
private Queue<T> DeletePending;
private bool Locked;
public OGLCachedResource(DeleteValue DeleteValueCallback) public OGLCachedResource(DeleteValue DeleteValueCallback)
{ {
if (DeleteValueCallback == null) if (DeleteValueCallback == null)
@ -48,11 +52,33 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Cache = new Dictionary<long, CacheBucket>(); Cache = new Dictionary<long, CacheBucket>();
SortedCache = new LinkedList<long>(); SortedCache = new LinkedList<long>();
DeletePending = new Queue<T>();
}
public void Lock()
{
Locked = true;
}
public void Unlock()
{
Locked = false;
while (DeletePending.TryDequeue(out T Value))
{
DeleteValueCallback(Value);
}
ClearCacheIfNeeded();
} }
public void AddOrUpdate(long Key, T Value, long Size) public void AddOrUpdate(long Key, T Value, long Size)
{ {
ClearCacheIfNeeded(); if (!Locked)
{
ClearCacheIfNeeded();
}
LinkedListNode<long> Node = SortedCache.AddLast(Key); LinkedListNode<long> Node = SortedCache.AddLast(Key);
@ -60,7 +86,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
if (Cache.TryGetValue(Key, out CacheBucket Bucket)) if (Cache.TryGetValue(Key, out CacheBucket Bucket))
{ {
DeleteValueCallback(Bucket.Value); if (Locked)
{
DeletePending.Enqueue(Bucket.Value);
}
else
{
DeleteValueCallback(Bucket.Value);
}
SortedCache.Remove(Bucket.Node); SortedCache.Remove(Bucket.Node);
@ -78,6 +111,12 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
Value = Bucket.Value; Value = Bucket.Value;
SortedCache.Remove(Bucket.Node);
LinkedListNode<long> Node = SortedCache.AddLast(Key);
Cache[Key] = new CacheBucket(Value, Bucket.DataSize, Node);
return true; return true;
} }

View file

@ -139,6 +139,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte); case GalTextureFormat.G8R8: return (PixelFormat.Rg, PixelType.UnsignedByte);
case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat); case GalTextureFormat.R16: return (PixelFormat.Red, PixelType.HalfFloat);
case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte); case GalTextureFormat.R8: return (PixelFormat.Red, PixelType.UnsignedByte);
case GalTextureFormat.ZF32: return (PixelFormat.DepthComponent, PixelType.Float);
} }
throw new NotImplementedException(Format.ToString()); throw new NotImplementedException(Format.ToString());

View file

@ -71,6 +71,18 @@ namespace Ryujinx.Graphics.Gal.OpenGL
IndexBuffer = new IbInfo(); IndexBuffer = new IbInfo();
} }
public void LockCaches()
{
VboCache.Lock();
IboCache.Lock();
}
public void UnlockCaches()
{
VboCache.Unlock();
IboCache.Unlock();
}
public void ClearBuffers(GalClearBufferFlags Flags) public void ClearBuffers(GalClearBufferFlags Flags)
{ {
ClearBufferMask Mask = ClearBufferMask.ColorBufferBit; ClearBufferMask Mask = ClearBufferMask.ColorBufferBit;
@ -223,7 +235,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw); GL.BufferData(BufferTarget.ElementArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
} }
public void SetVertexArray(int VbIndex, int Stride, long VboKey, GalVertexAttrib[] Attribs) public void SetVertexArray(int Stride, long VboKey, GalVertexAttrib[] Attribs)
{ {
if (!VboCache.TryGetValue(VboKey, out int VboHandle)) if (!VboCache.TryGetValue(VboKey, out int VboHandle))
{ {
@ -270,7 +282,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
} }
} }
public void SetIndexArray(long Key, int Size, GalIndexFormat Format) public void SetIndexArray(int Size, GalIndexFormat Format)
{ {
IndexBuffer.Type = OGLEnumConverter.GetDrawElementsType(Format); IndexBuffer.Type = OGLEnumConverter.GetDrawElementsType(Format);

View file

@ -26,6 +26,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
TextureCache = new OGLCachedResource<TCE>(DeleteTexture); TextureCache = new OGLCachedResource<TCE>(DeleteTexture);
} }
public void LockCache()
{
TextureCache.Lock();
}
public void UnlockCache()
{
TextureCache.Unlock();
}
private static void DeleteTexture(TCE CachedTexture) private static void DeleteTexture(TCE CachedTexture)
{ {
GL.DeleteTexture(CachedTexture.Handle); GL.DeleteTexture(CachedTexture.Handle);

View file

@ -73,6 +73,8 @@ namespace Ryujinx.HLE.Gpu.Engines
private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) private void VertexEndGl(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
{ {
LockCaches();
SetFrameBuffer(Vmm, 0); SetFrameBuffer(Vmm, 0);
long[] Keys = UploadShaders(Vmm); long[] Keys = UploadShaders(Vmm);
@ -90,6 +92,20 @@ namespace Ryujinx.HLE.Gpu.Engines
UploadTextures(Vmm, Keys); UploadTextures(Vmm, Keys);
UploadUniforms(Vmm); UploadUniforms(Vmm);
UploadVertexArrays(Vmm); UploadVertexArrays(Vmm);
UnlockCaches();
}
private void LockCaches()
{
Gpu.Renderer.Rasterizer.LockCaches();
Gpu.Renderer.Texture.LockCache();
}
private void UnlockCaches()
{
Gpu.Renderer.Rasterizer.UnlockCaches();
Gpu.Renderer.Texture.UnlockCache();
} }
private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry) private void ClearBuffers(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
@ -570,7 +586,7 @@ namespace Ryujinx.HLE.Gpu.Engines
Gpu.Renderer.Rasterizer.CreateIbo(IboKey, Data); Gpu.Renderer.Rasterizer.CreateIbo(IboKey, Data);
} }
Gpu.Renderer.Rasterizer.SetIndexArray(IboKey, IbSize, IndexFormat); Gpu.Renderer.Rasterizer.SetIndexArray(IbSize, IndexFormat);
} }
List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32]; List<GalVertexAttrib>[] Attribs = new List<GalVertexAttrib>[32];
@ -634,7 +650,7 @@ namespace Ryujinx.HLE.Gpu.Engines
Gpu.Renderer.Rasterizer.CreateVbo(VboKey, Data); Gpu.Renderer.Rasterizer.CreateVbo(VboKey, Data);
} }
Gpu.Renderer.Rasterizer.SetVertexArray(Index, Stride, VboKey, Attribs[Index].ToArray()); Gpu.Renderer.Rasterizer.SetVertexArray(Stride, VboKey, Attribs[Index].ToArray());
} }
GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff); GalPrimitiveType PrimType = (GalPrimitiveType)(PrimCtrl & 0xffff);

View file

@ -28,16 +28,26 @@ namespace Ryujinx.HLE.Gpu.Texture
{ {
switch (Texture.Format) switch (Texture.Format)
{ {
case GalTextureFormat.R32G32B32A32: return Texture.Width * Texture.Height * 16; case GalTextureFormat.R32G32B32A32:
case GalTextureFormat.R16G16B16A16: return Texture.Width * Texture.Height * 8; return Texture.Width * Texture.Height * 16;
case GalTextureFormat.A8B8G8R8: return Texture.Width * Texture.Height * 4;
case GalTextureFormat.R16_G16: return Texture.Width * Texture.Height * 4; case GalTextureFormat.R16G16B16A16:
case GalTextureFormat.R32: return Texture.Width * Texture.Height * 4; return Texture.Width * Texture.Height * 8;
case GalTextureFormat.A1B5G5R5: return Texture.Width * Texture.Height * 2;
case GalTextureFormat.B5G6R5: return Texture.Width * Texture.Height * 2; case GalTextureFormat.A8B8G8R8:
case GalTextureFormat.G8R8: return Texture.Width * Texture.Height * 2; case GalTextureFormat.R32:
case GalTextureFormat.R16: return Texture.Width * Texture.Height * 2; case GalTextureFormat.R16_G16:
case GalTextureFormat.R8: return Texture.Width * Texture.Height; case GalTextureFormat.ZF32:
return Texture.Width * Texture.Height * 4;
case GalTextureFormat.A1B5G5R5:
case GalTextureFormat.B5G6R5:
case GalTextureFormat.G8R8:
case GalTextureFormat.R16:
return Texture.Width * Texture.Height * 2;
case GalTextureFormat.R8:
return Texture.Width * Texture.Height;
case GalTextureFormat.BC1: case GalTextureFormat.BC1:
case GalTextureFormat.BC4: case GalTextureFormat.BC4:

View file

@ -26,6 +26,7 @@ namespace Ryujinx.HLE.Gpu.Texture
case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture); case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture);
case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture); case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture);
case GalTextureFormat.BC5: return Read16Bpt4x4(Memory, Texture); case GalTextureFormat.BC5: return Read16Bpt4x4(Memory, Texture);
case GalTextureFormat.ZF32: return Read4Bpp (Memory, Texture);
case GalTextureFormat.Astc2D4x4: return Read16Bpt4x4(Memory, Texture); case GalTextureFormat.Astc2D4x4: return Read16Bpt4x4(Memory, Texture);
} }

View file

@ -14,6 +14,10 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
{ {
private const string DefaultAudioOutput = "DeviceOut"; private const string DefaultAudioOutput = "DeviceOut";
private const int DefaultSampleRate = 48000;
private const int DefaultChannelsCount = 2;
private Dictionary<int, ServiceProcessRequest> m_Commands; private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands; public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
@ -122,7 +126,12 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
int SampleRate = Context.RequestData.ReadInt32(); int SampleRate = Context.RequestData.ReadInt32();
int Channels = Context.RequestData.ReadInt32(); int Channels = Context.RequestData.ReadInt32();
if (SampleRate != 48000) if (SampleRate == 0)
{
SampleRate = DefaultSampleRate;
}
if (SampleRate != DefaultSampleRate)
{ {
Context.Ns.Log.PrintWarning(LogClass.Audio, "Invalid sample rate!"); Context.Ns.Log.PrintWarning(LogClass.Audio, "Invalid sample rate!");
@ -133,7 +142,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
if (Channels == 0) if (Channels == 0)
{ {
Channels = 2; Channels = DefaultChannelsCount;
} }
KEvent ReleaseEvent = new KEvent(); KEvent ReleaseEvent = new KEvent();
@ -145,7 +154,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
IAalOutput AudioOut = Context.Ns.AudioOut; IAalOutput AudioOut = Context.Ns.AudioOut;
int Track = AudioOut.OpenTrack(SampleRate, 2, Callback, out AudioFormat Format); int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format);
MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track)); MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track));