Merge branch 'master' into patch-10
This commit is contained in:
commit
7436e37ae2
13 changed files with 160 additions and 32 deletions
|
@ -80,6 +80,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
{ ShaderIrInst.Frcp, GetFrcpExpr },
|
{ ShaderIrInst.Frcp, GetFrcpExpr },
|
||||||
{ ShaderIrInst.Frsq, GetFrsqExpr },
|
{ ShaderIrInst.Frsq, GetFrsqExpr },
|
||||||
{ ShaderIrInst.Fsin, GetFsinExpr },
|
{ ShaderIrInst.Fsin, GetFsinExpr },
|
||||||
|
{ ShaderIrInst.Fsqrt, GetFsqrtExpr },
|
||||||
{ ShaderIrInst.Ftos, GetFtosExpr },
|
{ ShaderIrInst.Ftos, GetFtosExpr },
|
||||||
{ ShaderIrInst.Ftou, GetFtouExpr },
|
{ ShaderIrInst.Ftou, GetFtouExpr },
|
||||||
{ ShaderIrInst.Ipa, GetIpaExpr },
|
{ ShaderIrInst.Ipa, GetIpaExpr },
|
||||||
|
@ -716,6 +717,8 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
private string GetFsinExpr(ShaderIrOp Op) => GetUnaryCall(Op, "sin");
|
private string GetFsinExpr(ShaderIrOp Op) => GetUnaryCall(Op, "sin");
|
||||||
|
|
||||||
|
private string GetFsqrtExpr(ShaderIrOp Op) => GetUnaryCall(Op, "sqrt");
|
||||||
|
|
||||||
private string GetFtosExpr(ShaderIrOp Op)
|
private string GetFtosExpr(ShaderIrOp Op)
|
||||||
{
|
{
|
||||||
return "int(" + GetOperExpr(Op, Op.OperandA) + ")";
|
return "int(" + GetOperExpr(Op, Op.OperandA) + ")";
|
||||||
|
|
|
@ -217,7 +217,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
public static void Mufu(ShaderIrBlock Block, long OpCode)
|
public static void Mufu(ShaderIrBlock Block, long OpCode)
|
||||||
{
|
{
|
||||||
int SubOp = (int)(OpCode >> 20) & 7;
|
int SubOp = (int)(OpCode >> 20) & 0xf;
|
||||||
|
|
||||||
bool AbsA = ((OpCode >> 46) & 1) != 0;
|
bool AbsA = ((OpCode >> 46) & 1) != 0;
|
||||||
bool NegA = ((OpCode >> 48) & 1) != 0;
|
bool NegA = ((OpCode >> 48) & 1) != 0;
|
||||||
|
@ -226,12 +226,13 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
|
|
||||||
switch (SubOp)
|
switch (SubOp)
|
||||||
{
|
{
|
||||||
case 0: Inst = ShaderIrInst.Fcos; break;
|
case 0: Inst = ShaderIrInst.Fcos; break;
|
||||||
case 1: Inst = ShaderIrInst.Fsin; break;
|
case 1: Inst = ShaderIrInst.Fsin; break;
|
||||||
case 2: Inst = ShaderIrInst.Fex2; break;
|
case 2: Inst = ShaderIrInst.Fex2; break;
|
||||||
case 3: Inst = ShaderIrInst.Flg2; break;
|
case 3: Inst = ShaderIrInst.Flg2; break;
|
||||||
case 4: Inst = ShaderIrInst.Frcp; break;
|
case 4: Inst = ShaderIrInst.Frcp; break;
|
||||||
case 5: Inst = ShaderIrInst.Frsq; break;
|
case 5: Inst = ShaderIrInst.Frsq; break;
|
||||||
|
case 8: Inst = ShaderIrInst.Fsqrt; break;
|
||||||
|
|
||||||
default: throw new NotImplementedException(SubOp.ToString());
|
default: throw new NotImplementedException(SubOp.ToString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace Ryujinx.Graphics.Gal.Shader
|
||||||
Frcp,
|
Frcp,
|
||||||
Frsq,
|
Frsq,
|
||||||
Fsin,
|
Fsin,
|
||||||
|
Fsqrt,
|
||||||
Ftos,
|
Ftos,
|
||||||
Ftou,
|
Ftou,
|
||||||
Ipa,
|
Ipa,
|
||||||
|
|
|
@ -248,6 +248,15 @@ namespace Ryujinx.HLE.Gpu
|
||||||
|
|
||||||
int TextureHandle = Vmm.ReadInt32(Position);
|
int TextureHandle = Vmm.ReadInt32(Position);
|
||||||
|
|
||||||
|
if (TextureHandle == 0)
|
||||||
|
{
|
||||||
|
//TODO: Is this correct?
|
||||||
|
//Some games like puyo puyo will have 0 handles.
|
||||||
|
//It may be just normal behaviour or a bug caused by sync issues.
|
||||||
|
//The game does initialize the value properly after through.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int TicIndex = (TextureHandle >> 0) & 0xfffff;
|
int TicIndex = (TextureHandle >> 0) & 0xfffff;
|
||||||
int TscIndex = (TextureHandle >> 20) & 0xfff;
|
int TscIndex = (TextureHandle >> 20) & 0xfff;
|
||||||
|
|
||||||
|
@ -314,7 +323,7 @@ namespace Ryujinx.HLE.Gpu
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int Cbuf = 0; Cbuf < ConstBuffers.Length; Cbuf++)
|
for (int Cbuf = 0; Cbuf < ConstBuffers[Index].Length; Cbuf++)
|
||||||
{
|
{
|
||||||
ConstBuffer Cb = ConstBuffers[Index][Cbuf];
|
ConstBuffer Cb = ConstBuffers[Index][Cbuf];
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,17 @@ namespace Ryujinx.HLE.Gpu
|
||||||
|
|
||||||
TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
|
TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7);
|
||||||
|
|
||||||
|
if (Swizzle == TextureSwizzle.BlockLinear ||
|
||||||
|
Swizzle == TextureSwizzle.BlockLinearColorKey)
|
||||||
|
{
|
||||||
|
TextureAddress &= ~0x1ffL;
|
||||||
|
}
|
||||||
|
else if (Swizzle == TextureSwizzle.Pitch ||
|
||||||
|
Swizzle == TextureSwizzle.PitchColorKey)
|
||||||
|
{
|
||||||
|
TextureAddress &= ~0x1fL;
|
||||||
|
}
|
||||||
|
|
||||||
int Pitch = (Tic[3] & 0xffff) << 5;
|
int Pitch = (Tic[3] & 0xffff) << 5;
|
||||||
|
|
||||||
int BlockHeightLog2 = (Tic[3] >> 3) & 7;
|
int BlockHeightLog2 = (Tic[3] >> 3) & 7;
|
||||||
|
|
|
@ -10,6 +10,7 @@ namespace Ryujinx.HLE.Gpu
|
||||||
{
|
{
|
||||||
switch (Texture.Swizzle)
|
switch (Texture.Swizzle)
|
||||||
{
|
{
|
||||||
|
case TextureSwizzle._1dBuffer:
|
||||||
case TextureSwizzle.Pitch:
|
case TextureSwizzle.Pitch:
|
||||||
case TextureSwizzle.PitchColorKey:
|
case TextureSwizzle.PitchColorKey:
|
||||||
return new LinearSwizzle(Texture.Pitch, Bpp);
|
return new LinearSwizzle(Texture.Pitch, Bpp);
|
||||||
|
|
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameter.cs
Normal file
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameter.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct AudioRendererParameter
|
||||||
|
{
|
||||||
|
public int SampleRate;
|
||||||
|
public int SampleCount;
|
||||||
|
public int Unknown8;
|
||||||
|
public int UnknownC;
|
||||||
|
public int VoiceCount;
|
||||||
|
public int SinkCount;
|
||||||
|
public int EffectCount;
|
||||||
|
public int Unknown1C;
|
||||||
|
public int Unknown20;
|
||||||
|
public int SplitterCount;
|
||||||
|
public int Unknown28;
|
||||||
|
public int Unknown2C;
|
||||||
|
public int Revision;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
|
using ChocolArm64.Memory;
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using Ryujinx.HLE.OsHle.Handles;
|
using Ryujinx.HLE.OsHle.Handles;
|
||||||
using Ryujinx.HLE.OsHle.Ipc;
|
using Ryujinx.HLE.OsHle.Ipc;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
{
|
{
|
||||||
|
@ -14,7 +16,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
|
||||||
private KEvent UpdateEvent;
|
private KEvent UpdateEvent;
|
||||||
|
|
||||||
public IAudioRenderer()
|
private AudioRendererParameter Params;
|
||||||
|
|
||||||
|
public IAudioRenderer(AudioRendererParameter Params)
|
||||||
{
|
{
|
||||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||||
{
|
{
|
||||||
|
@ -26,34 +30,58 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdateEvent = new KEvent();
|
UpdateEvent = new KEvent();
|
||||||
|
|
||||||
|
this.Params = Params;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
||||||
{
|
{
|
||||||
return RequestUpdateAudioRendererMethod(Context, Context.Request.ReceiveBuff[0].Position);
|
|
||||||
|
return RequestUpdateAudioRendererMethod(Context, Context.Request.ReceiveBuff[0].Position, Context.Request.SendBuff[0].Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long RequestUpdateAudioRendererAuto(ServiceCtx Context)
|
public long RequestUpdateAudioRendererAuto(ServiceCtx Context)
|
||||||
{
|
{
|
||||||
return RequestUpdateAudioRendererMethod(Context, Context.Request.GetBufferType0x21().Position);
|
return RequestUpdateAudioRendererMethod(Context, Context.Request.GetBufferType0x22().Position, Context.Request.GetBufferType0x21().Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long RequestUpdateAudioRendererMethod(ServiceCtx Context, long Position)
|
public long RequestUpdateAudioRendererMethod(ServiceCtx Context, long OutputPosition, long InputPosition)
|
||||||
{
|
{
|
||||||
//(buffer<unknown, 5, 0>) -> (buffer<unknown, 6, 0>, buffer<unknown, 6, 0>)
|
UpdateDataHeader InputDataHeader = AMemoryHelper.Read<UpdateDataHeader>(Context.Memory, InputPosition);
|
||||||
|
|
||||||
//0x40 bytes header
|
int MemoryPoolOffset = Marshal.SizeOf(InputDataHeader) + InputDataHeader.BehaviorSize;
|
||||||
Context.Memory.WriteInt32(Position + 0x4, 0xb0); //Behavior Out State Size? (note: this is the last section)
|
|
||||||
Context.Memory.WriteInt32(Position + 0x8, 0x18e0); //Memory Pool Out State Size?
|
|
||||||
Context.Memory.WriteInt32(Position + 0xc, 0x600); //Voice Out State Size?
|
|
||||||
Context.Memory.WriteInt32(Position + 0x14, 0xe0); //Effect Out State Size?
|
|
||||||
Context.Memory.WriteInt32(Position + 0x1c, 0x20); //Sink Out State Size?
|
|
||||||
Context.Memory.WriteInt32(Position + 0x20, 0x10); //Performance Out State Size?
|
|
||||||
Context.Memory.WriteInt32(Position + 0x3c, 0x20e0); //Total Size (including 0x40 bytes header)
|
|
||||||
|
|
||||||
for (int Offset = 0x40; Offset < 0x40 + 0x18e0; Offset += 0x10)
|
UpdateDataHeader OutputDataHeader = new UpdateDataHeader();
|
||||||
|
|
||||||
|
OutputDataHeader.Revision = Params.Revision;
|
||||||
|
OutputDataHeader.BehaviorSize = 0xb0;
|
||||||
|
OutputDataHeader.MemoryPoolsSize = (Params.EffectCount + (Params.VoiceCount * 4)) * 0x10;
|
||||||
|
OutputDataHeader.VoicesSize = Params.VoiceCount * 0x10;
|
||||||
|
OutputDataHeader.EffectsSize = Params.EffectCount * 0x10;
|
||||||
|
OutputDataHeader.SinksSize = Params.SinkCount * 0x20;
|
||||||
|
OutputDataHeader.PerformanceManagerSize = 0x10;
|
||||||
|
OutputDataHeader.TotalSize = Marshal.SizeOf(OutputDataHeader) + OutputDataHeader.BehaviorSize + OutputDataHeader.MemoryPoolsSize +
|
||||||
|
OutputDataHeader.VoicesSize + OutputDataHeader.EffectsSize + OutputDataHeader.SinksSize + OutputDataHeader.PerformanceManagerSize;
|
||||||
|
|
||||||
|
AMemoryHelper.Write(Context.Memory, OutputPosition, OutputDataHeader);
|
||||||
|
|
||||||
|
|
||||||
|
for (int Offset = 0x40; Offset < 0x40 + OutputDataHeader.MemoryPoolsSize; Offset += 0x10, MemoryPoolOffset += 0x20)
|
||||||
{
|
{
|
||||||
Context.Memory.WriteInt32(Position + Offset, 5);
|
MemoryPoolStates PoolState = (MemoryPoolStates) Context.Memory.ReadInt32(InputPosition + MemoryPoolOffset + 0x10);
|
||||||
|
|
||||||
|
if (PoolState == MemoryPoolStates.RequestAttach)
|
||||||
|
{
|
||||||
|
Context.Memory.WriteInt32(OutputPosition + Offset, (int)MemoryPoolStates.Attached);
|
||||||
|
}
|
||||||
|
else if (PoolState == MemoryPoolStates.RequestDetach)
|
||||||
|
{
|
||||||
|
Context.Memory.WriteInt32(OutputPosition + Offset, (int)MemoryPoolStates.Detached);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Context.Memory.WriteInt32(OutputPosition + Offset, (int)PoolState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: We shouldn't be signaling this here.
|
//TODO: We shouldn't be signaling this here.
|
||||||
|
@ -98,4 +126,4 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using Ryujinx.HLE.OsHle.Ipc;
|
using Ryujinx.HLE.OsHle.Ipc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
{
|
{
|
||||||
|
@ -29,7 +30,23 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
{
|
{
|
||||||
//Same buffer as GetAudioRendererWorkBufferSize is receive here.
|
//Same buffer as GetAudioRendererWorkBufferSize is receive here.
|
||||||
|
|
||||||
MakeObject(Context, new IAudioRenderer());
|
AudioRendererParameter Params = new AudioRendererParameter();
|
||||||
|
|
||||||
|
Params.SampleRate = Context.RequestData.ReadInt32();
|
||||||
|
Params.SampleCount = Context.RequestData.ReadInt32();
|
||||||
|
Params.Unknown8 = Context.RequestData.ReadInt32();
|
||||||
|
Params.UnknownC = Context.RequestData.ReadInt32();
|
||||||
|
Params.VoiceCount = Context.RequestData.ReadInt32();
|
||||||
|
Params.SinkCount = Context.RequestData.ReadInt32();
|
||||||
|
Params.EffectCount = Context.RequestData.ReadInt32();
|
||||||
|
Params.Unknown1C = Context.RequestData.ReadInt32();
|
||||||
|
Params.Unknown20 = Context.RequestData.ReadInt32();
|
||||||
|
Params.SplitterCount = Context.RequestData.ReadInt32();
|
||||||
|
Params.Unknown28 = Context.RequestData.ReadInt32();
|
||||||
|
Params.Unknown2C = Context.RequestData.ReadInt32();
|
||||||
|
Params.Revision = Context.RequestData.ReadInt32();
|
||||||
|
|
||||||
|
MakeObject(Context, new IAudioRenderer(Params));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +65,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
long Unknown24 = Context.RequestData.ReadUInt32();
|
long Unknown24 = Context.RequestData.ReadUInt32();
|
||||||
long Unknown28 = Context.RequestData.ReadUInt32(); //SplitterCount
|
long Unknown28 = Context.RequestData.ReadUInt32(); //SplitterCount
|
||||||
long Unknown2c = Context.RequestData.ReadUInt32(); //Not used here in FW3.0.1
|
long Unknown2c = Context.RequestData.ReadUInt32(); //Not used here in FW3.0.1
|
||||||
int RevMagic = Context.RequestData.ReadInt32();
|
int RevMagic = Context.RequestData.ReadInt32();
|
||||||
|
|
||||||
int Version = (RevMagic - Rev0Magic) >> 24;
|
int Version = (RevMagic - Rev0Magic) >> 24;
|
||||||
|
|
||||||
|
|
13
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs
Normal file
13
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
{
|
||||||
|
enum MemoryPoolStates : int
|
||||||
|
{
|
||||||
|
Invalid = 0x0,
|
||||||
|
Unknown = 0x1,
|
||||||
|
RequestDetach = 0x2,
|
||||||
|
Detached = 0x3,
|
||||||
|
RequestAttach = 0x4,
|
||||||
|
Attached = 0x5,
|
||||||
|
Released = 0x6,
|
||||||
|
}
|
||||||
|
}
|
22
Ryujinx.HLE/OsHle/Services/Aud/UpdateDataHeader.cs
Normal file
22
Ryujinx.HLE/OsHle/Services/Aud/UpdateDataHeader.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
{
|
||||||
|
struct UpdateDataHeader
|
||||||
|
{
|
||||||
|
public int Revision;
|
||||||
|
public int BehaviorSize;
|
||||||
|
public int MemoryPoolsSize;
|
||||||
|
public int VoicesSize;
|
||||||
|
public int VoiceResourceSize;
|
||||||
|
public int EffectsSize;
|
||||||
|
public int MixesSize;
|
||||||
|
public int SinksSize;
|
||||||
|
public int PerformanceManagerSize;
|
||||||
|
public int Unknown24;
|
||||||
|
public int Unknown28;
|
||||||
|
public int Unknown2C;
|
||||||
|
public int Unknown30;
|
||||||
|
public int Unknown34;
|
||||||
|
public int Unknown38;
|
||||||
|
public int TotalSize;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,14 +24,14 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvMap
|
||||||
this.Size = Size;
|
this.Size = Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long IncrementRefCount()
|
public void IncrementRefCount()
|
||||||
{
|
{
|
||||||
return Interlocked.Increment(ref Dupes);
|
Interlocked.Increment(ref Dupes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long DecrementRefCount()
|
public long DecrementRefCount()
|
||||||
{
|
{
|
||||||
return Interlocked.Decrement(ref Dupes);
|
return Interlocked.Decrement(ref Dupes) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -163,9 +163,9 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvMap
|
||||||
return NvResult.InvalidInput;
|
return NvResult.InvalidInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
long RefCount = Map.DecrementRefCount();
|
long OldRefCount = Map.DecrementRefCount();
|
||||||
|
|
||||||
if (RefCount <= 0)
|
if (OldRefCount <= 1)
|
||||||
{
|
{
|
||||||
DeleteNvMap(Context, Args.Handle);
|
DeleteNvMap(Context, Args.Handle);
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvMap
|
||||||
Args.Flags = FlagNotFreedYet;
|
Args.Flags = FlagNotFreedYet;
|
||||||
}
|
}
|
||||||
|
|
||||||
Args.RefCount = RefCount;
|
Args.RefCount = OldRefCount;
|
||||||
Args.Size = Map.Size;
|
Args.Size = Map.Size;
|
||||||
|
|
||||||
AMemoryHelper.Write(Context.Memory, OutputPosition, Args);
|
AMemoryHelper.Write(Context.Memory, OutputPosition, Args);
|
||||||
|
|
Loading…
Reference in a new issue