forked from Mirror/Ryujinx
vi: Implement GetIndirectLayerImageRequiredMemoryInfo (#1415)
This implement GetIndirectLayerImageRequiredMemoryInfo call from vi service, accordingly to RE. Thanks to Thog and gdkchan for helping me to understand some GPU things. Close #942
This commit is contained in:
parent
c6e12949e5
commit
9e141bc3da
2 changed files with 50 additions and 1 deletions
|
@ -8,6 +8,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
|
||||||
Success = 0,
|
Success = 0,
|
||||||
|
|
||||||
InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
|
InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
|
||||||
|
InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId,
|
||||||
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId
|
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Cpu;
|
using Ryujinx.Cpu;
|
||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||||
|
@ -190,7 +191,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
public ResultCode SetLayerScalingMode(ServiceCtx context)
|
public ResultCode SetLayerScalingMode(ServiceCtx context)
|
||||||
{
|
{
|
||||||
int scalingMode = context.RequestData.ReadInt32();
|
int scalingMode = context.RequestData.ReadInt32();
|
||||||
long unknown = context.RequestData.ReadInt64();
|
long layerId = context.RequestData.ReadInt64();
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
}
|
}
|
||||||
|
@ -235,6 +236,53 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Command(2460)]
|
||||||
|
// GetIndirectLayerImageRequiredMemoryInfo(u64 width, u64 height) -> (u64 size, u64 alignment)
|
||||||
|
public ResultCode GetIndirectLayerImageRequiredMemoryInfo(ServiceCtx context)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// Doesn't occur in our case.
|
||||||
|
if (sizePtr == null || address_alignmentPtr == null)
|
||||||
|
{
|
||||||
|
return ResultCode.InvalidArguments;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int width = (int)context.RequestData.ReadUInt64();
|
||||||
|
int height = (int)context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
|
if (height < 0 || width < 0)
|
||||||
|
{
|
||||||
|
return ResultCode.InvalidLayerSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
// Doesn't occur in our case.
|
||||||
|
if (!service_initialized)
|
||||||
|
{
|
||||||
|
return ResultCode.InvalidArguments;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const ulong defaultAlignment = 0x1000;
|
||||||
|
const ulong defaultSize = 0x20000;
|
||||||
|
|
||||||
|
// NOTE: The official service setup a A8B8G8R8 texture with a linear layout and then query its size.
|
||||||
|
// As we don't need this texture on the emulator, we can just simplify this logic and directly
|
||||||
|
// do a linear layout size calculation. (stride * height * bytePerPixel)
|
||||||
|
int pitch = BitUtils.AlignUp(BitUtils.DivRoundUp(width * 32, 8), 64);
|
||||||
|
int memorySize = pitch * BitUtils.AlignUp(height, 64);
|
||||||
|
ulong requiredMemorySize = (ulong)BitUtils.AlignUp(memorySize, (int)defaultAlignment);
|
||||||
|
ulong size = (requiredMemorySize + defaultSize - 1) / defaultSize * defaultSize;
|
||||||
|
|
||||||
|
context.ResponseData.Write(size);
|
||||||
|
context.ResponseData.Write(defaultAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultCode.Success;
|
||||||
|
}
|
||||||
|
|
||||||
[Command(5202)]
|
[Command(5202)]
|
||||||
// GetDisplayVsyncEvent(u64) -> handle<copy>
|
// GetDisplayVsyncEvent(u64) -> handle<copy>
|
||||||
public ResultCode GetDisplayVSyncEvent(ServiceCtx context)
|
public ResultCode GetDisplayVSyncEvent(ServiceCtx context)
|
||||||
|
|
Loading…
Reference in a new issue