diff --git a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
index 2fc315c3cd..ffca6f339b 100644
--- a/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs
@@ -66,12 +66,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
///
/// CPU virtual address to map into
/// Size in bytes of the mapping
+ /// Required alignment of the GPU virtual address in bytes
/// GPU virtual address where the range was mapped, or an all ones mask in case of failure
- public ulong Map(ulong pa, ulong size)
+ public ulong MapAllocate(ulong pa, ulong size, ulong alignment)
{
lock (_pageTable)
{
- ulong va = GetFreePosition(size);
+ ulong va = GetFreePosition(size, alignment);
if (va != PteUnmapped)
{
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
index 008c6059ba..6653c0f0eb 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/NvHostAsGpuDeviceFile.cs
@@ -1,10 +1,12 @@
-using Ryujinx.Common.Logging;
+using Ryujinx.Common;
+using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
using System;
using System.Collections.Concurrent;
+using System.Diagnostics;
namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
{
@@ -165,7 +167,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
private NvInternalResult MapBufferEx(ref MapBufferExArguments arguments)
{
- const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16} and size 0x{1:x16}!";
+ const string mapErrorMsg = "Failed to map fixed buffer with offset 0x{0:x16}, size 0x{1:x16} and alignment 0x{2:x16}!";
AddressSpaceContext addressSpaceContext = GetAddressSpaceContext(Context);
@@ -178,6 +180,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
return NvInternalResult.InvalidInput;
}
+ ulong pageSize = (ulong)arguments.PageSize;
+
+ if (pageSize == 0)
+ {
+ pageSize = (ulong)map.Align;
+ }
+
long physicalAddress;
if ((arguments.Flags & AddressSpaceFlags.RemapSubRange) != 0)
@@ -192,7 +201,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
if ((long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)virtualAddress, (ulong)arguments.MappingSize) < 0)
{
- string message = string.Format(mapErrorMsg, virtualAddress, arguments.MappingSize);
+ string message = string.Format(mapErrorMsg, virtualAddress, arguments.MappingSize, pageSize);
Logger.PrintWarning(LogClass.ServiceNv, message);
@@ -229,13 +238,13 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
if (!virtualAddressAllocated)
{
- if (addressSpaceContext.ValidateFixedBuffer(arguments.Offset, size))
+ if (addressSpaceContext.ValidateFixedBuffer(arguments.Offset, size, pageSize))
{
arguments.Offset = (long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)arguments.Offset, (ulong)size);
}
else
{
- string message = string.Format(mapErrorMsg, arguments.Offset, size);
+ string message = string.Format(mapErrorMsg, arguments.Offset, size, pageSize);
Logger.PrintWarning(LogClass.ServiceNv, message);
@@ -244,7 +253,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu
}
else
{
- arguments.Offset = (long)addressSpaceContext.Gmm.Map((ulong)physicalAddress, (ulong)size);
+ arguments.Offset = (long)addressSpaceContext.Gmm.MapAllocate((ulong)physicalAddress, (ulong)size, pageSize);
}
if (arguments.Offset < 0)
diff --git a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
index 951994efcb..d39be2977c 100644
--- a/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
+++ b/Ryujinx.HLE/HOS/Services/Nv/NvDrvServices/NvHostAsGpu/Types/AddressSpaceContext.cs
@@ -48,7 +48,7 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
_reservations = new SortedList();
}
- public bool ValidateFixedBuffer(long position, long size)
+ public bool ValidateFixedBuffer(long position, long size, ulong alignment)
{
long mapEnd = position + size;
@@ -58,8 +58,8 @@ namespace Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvHostAsGpu.Types
return false;
}
- // Check if address is page aligned.
- if ((position & (long)MemoryManager.PageMask) != 0)
+ // Check if address is aligned.
+ if ((position & (long)(alignment - 1)) != 0)
{
return false;
}