Implement GetVaRegions on nvservices (#2621)

* Implement GetVaRegions on nvservices

* This would just result in 0
This commit is contained in:
gdkchan 2021-09-11 17:39:02 -03:00 committed by GitHub
parent a4089fc878
commit 016fc64b3d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 9 deletions

View file

@ -5,11 +5,39 @@ using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostChannel;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
using Ryujinx.Memory; using Ryujinx.Memory;
using System; using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{ {
class NvHostAsGpuDeviceFile : NvDeviceFile class NvHostAsGpuDeviceFile : NvDeviceFile
{ {
private const uint SmallPageSize = 0x1000;
private const uint BigPageSize = 0x10000;
private static readonly uint[] _pageSizes = new uint[] { SmallPageSize, BigPageSize };
private const ulong SmallRegionLimit = 0x400000000UL; // 16 GB
private const ulong DefaultUserSize = 1UL << 37;
private struct VmRegion
{
public ulong Start { get; }
public ulong Limit { get; }
public VmRegion(ulong start, ulong limit)
{
Start = start;
Limit = limit;
}
}
private static readonly VmRegion[] _vmRegions = new VmRegion[]
{
new VmRegion((ulong)BigPageSize << 16, SmallRegionLimit),
new VmRegion(SmallRegionLimit, DefaultUserSize)
};
private readonly AddressSpaceContext _asContext; private readonly AddressSpaceContext _asContext;
private readonly NvMemoryAllocator _memoryAllocator; private readonly NvMemoryAllocator _memoryAllocator;
@ -296,7 +324,31 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult GetVaRegions(ref GetVaRegionsArguments arguments) private NvInternalResult GetVaRegions(ref GetVaRegionsArguments arguments)
{ {
Logger.Stub?.PrintStub(LogClass.ServiceNv); int vaRegionStructSize = Unsafe.SizeOf<VaRegion>();
Debug.Assert(vaRegionStructSize == 0x18);
Debug.Assert(_pageSizes.Length == 2);
uint writeEntries = (uint)(arguments.BufferSize / vaRegionStructSize);
if (writeEntries > _pageSizes.Length)
{
writeEntries = (uint)_pageSizes.Length;
}
for (uint i = 0; i < writeEntries; i++)
{
ref var region = ref arguments.Regions[(int)i];
var vmRegion = _vmRegions[i];
uint pageSize = _pageSizes[i];
region.PageSize = pageSize;
region.Offset = vmRegion.Start;
region.Pages = (vmRegion.Limit - vmRegion.Start) / pageSize;
region.Padding = 0;
}
arguments.BufferSize = (uint)(_pageSizes.Length * vaRegionStructSize);
return NvInternalResult.Success; return NvInternalResult.Success;
} }

View file

@ -1,4 +1,5 @@
using System.Runtime.InteropServices; using Ryujinx.Common.Memory;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
{ {
@ -6,18 +7,17 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
struct VaRegion struct VaRegion
{ {
public ulong Offset; public ulong Offset;
public uint PageSize; public uint PageSize;
public uint Padding; public uint Padding;
public ulong Pages; public ulong Pages;
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
struct GetVaRegionsArguments struct GetVaRegionsArguments
{ {
public ulong Unused; public ulong Unused;
public uint BufferSize; public uint BufferSize;
public uint Padding; public uint Padding;
public VaRegion Region0; public Array2<VaRegion> Regions;
public VaRegion Region1;
} }
} }