mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-08 20:02:39 +00:00
Merge branch 'master' into patch-3
This commit is contained in:
commit
1f8206c12b
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue