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:
Ac_K 2020-07-23 12:25:41 +02:00 committed by GitHub
parent c6e12949e5
commit 9e141bc3da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 1 deletions

View file

@ -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
} }
} }

View file

@ -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)