Add a separate device memory manager (#6153)

* Add a separate device memory manager

* Still need this

* Device writes are always tracked

* Device writes are always tracked (2)

* Rename more instances of gmm to mm
This commit is contained in:
gdkchan 2024-01-22 17:14:46 -03:00 committed by GitHub
parent 90455a05e6
commit f241f88558
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 555 additions and 157 deletions

View file

@ -12,10 +12,10 @@ namespace Ryujinx.Graphics.Nvdec
public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
{
PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
PictureInfo pictureInfo = rm.MemoryManager.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
H264PictureInfo info = pictureInfo.Convert();
ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize);
ReadOnlySpan<byte> bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize);
int width = (int)pictureInfo.PicWidthInMbs * MbSizeInPixels;
int height = (int)pictureInfo.PicHeightInMbs * MbSizeInPixels;
@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Nvdec
if (outputSurface.Field == FrameField.Progressive)
{
SurfaceWriter.Write(
rm.Gmm,
rm.MemoryManager,
outputSurface,
lumaOffset + pictureInfo.LumaFrameOffset,
chromaOffset + pictureInfo.ChromaFrameOffset);
@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Nvdec
else
{
SurfaceWriter.WriteInterlaced(
rm.Gmm,
rm.MemoryManager,
outputSurface,
lumaOffset + pictureInfo.LumaTopFieldOffset,
chromaOffset + pictureInfo.ChromaTopFieldOffset,

View file

@ -1,4 +1,4 @@
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Video;
using System;
using System.Diagnostics;
@ -27,11 +27,11 @@ namespace Ryujinx.Graphics.Nvdec.Image
private readonly CacheItem[] _pool = new CacheItem[MaxItems];
private readonly MemoryManager _gmm;
private readonly DeviceMemoryManager _mm;
public SurfaceCache(MemoryManager gmm)
public SurfaceCache(DeviceMemoryManager mm)
{
_gmm = gmm;
_mm = mm;
}
public ISurface Get(IDecoder decoder, uint lumaOffset, uint chromaOffset, int width, int height)
@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
if ((lumaOffset | chromaOffset) != 0)
{
SurfaceReader.Read(_gmm, surface, lumaOffset, chromaOffset);
SurfaceReader.Read(_mm, surface, lumaOffset, chromaOffset);
}
MoveToFront(i);
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
if ((lumaOffset | chromaOffset) != 0)
{
SurfaceReader.Read(_gmm, surface, lumaOffset, chromaOffset);
SurfaceReader.Read(_mm, surface, lumaOffset, chromaOffset);
}
MoveToFront(MaxItems - 1);

View file

@ -1,5 +1,5 @@
using Ryujinx.Common;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Texture;
using Ryujinx.Graphics.Video;
using System;
@ -11,13 +11,13 @@ namespace Ryujinx.Graphics.Nvdec.Image
{
static class SurfaceReader
{
public static void Read(MemoryManager gmm, ISurface surface, uint lumaOffset, uint chromaOffset)
public static void Read(DeviceMemoryManager mm, ISurface surface, uint lumaOffset, uint chromaOffset)
{
int width = surface.Width;
int height = surface.Height;
int stride = surface.Stride;
ReadOnlySpan<byte> luma = gmm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1));
ReadOnlySpan<byte> luma = mm.DeviceGetSpan(lumaOffset, GetBlockLinearSize(width, height, 1));
ReadLuma(surface.YPlane.AsSpan(), luma, stride, width, height);
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
int uvHeight = surface.UvHeight;
int uvStride = surface.UvStride;
ReadOnlySpan<byte> chroma = gmm.DeviceGetSpan(chromaOffset, GetBlockLinearSize(uvWidth, uvHeight, 2));
ReadOnlySpan<byte> chroma = mm.DeviceGetSpan(chromaOffset, GetBlockLinearSize(uvWidth, uvHeight, 2));
ReadChroma(surface.UPlane.AsSpan(), surface.VPlane.AsSpan(), chroma, uvStride, uvWidth, uvHeight);
}

View file

@ -1,5 +1,5 @@
using Ryujinx.Common;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Texture;
using Ryujinx.Graphics.Video;
using System;
@ -12,11 +12,11 @@ namespace Ryujinx.Graphics.Nvdec.Image
{
static class SurfaceWriter
{
public static void Write(MemoryManager gmm, ISurface surface, uint lumaOffset, uint chromaOffset)
public static void Write(DeviceMemoryManager mm, ISurface surface, uint lumaOffset, uint chromaOffset)
{
int lumaSize = GetBlockLinearSize(surface.Width, surface.Height, 1);
using var luma = gmm.GetWritableRegion(ExtendOffset(lumaOffset), lumaSize);
using var luma = mm.GetWritableRegion(ExtendOffset(lumaOffset), lumaSize);
WriteLuma(
luma.Memory.Span,
@ -27,7 +27,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
int chromaSize = GetBlockLinearSize(surface.UvWidth, surface.UvHeight, 2);
using var chroma = gmm.GetWritableRegion(ExtendOffset(chromaOffset), chromaSize);
using var chroma = mm.GetWritableRegion(ExtendOffset(chromaOffset), chromaSize);
WriteChroma(
chroma.Memory.Span,
@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Nvdec.Image
}
public static void WriteInterlaced(
MemoryManager gmm,
DeviceMemoryManager mm,
ISurface surface,
uint lumaTopOffset,
uint chromaTopOffset,
@ -48,8 +48,8 @@ namespace Ryujinx.Graphics.Nvdec.Image
{
int lumaSize = GetBlockLinearSize(surface.Width, surface.Height / 2, 1);
using var lumaTop = gmm.GetWritableRegion(ExtendOffset(lumaTopOffset), lumaSize);
using var lumaBottom = gmm.GetWritableRegion(ExtendOffset(lumaBottomOffset), lumaSize);
using var lumaTop = mm.GetWritableRegion(ExtendOffset(lumaTopOffset), lumaSize);
using var lumaBottom = mm.GetWritableRegion(ExtendOffset(lumaBottomOffset), lumaSize);
WriteLuma(
lumaTop.Memory.Span,
@ -67,8 +67,8 @@ namespace Ryujinx.Graphics.Nvdec.Image
int chromaSize = GetBlockLinearSize(surface.UvWidth, surface.UvHeight / 2, 2);
using var chromaTop = gmm.GetWritableRegion(ExtendOffset(chromaTopOffset), chromaSize);
using var chromaBottom = gmm.GetWritableRegion(ExtendOffset(chromaBottomOffset), chromaSize);
using var chromaTop = mm.GetWritableRegion(ExtendOffset(chromaTopOffset), chromaSize);
using var chromaBottom = mm.GetWritableRegion(ExtendOffset(chromaBottomOffset), chromaSize);
WriteChroma(
chromaTop.Memory.Span,

View file

@ -1,23 +1,23 @@
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using System;
namespace Ryujinx.Graphics.Nvdec
{
static class MemoryExtensions
{
public static T DeviceRead<T>(this MemoryManager gmm, uint offset) where T : unmanaged
public static T DeviceRead<T>(this DeviceMemoryManager gmm, uint offset) where T : unmanaged
{
return gmm.Read<T>((ulong)offset << 8);
return gmm.Read<T>(ExtendOffset(offset));
}
public static ReadOnlySpan<byte> DeviceGetSpan(this MemoryManager gmm, uint offset, int size)
public static ReadOnlySpan<byte> DeviceGetSpan(this DeviceMemoryManager gmm, uint offset, int size)
{
return gmm.GetSpan((ulong)offset << 8, size);
return gmm.GetSpan(ExtendOffset(offset), size);
}
public static void DeviceWrite(this MemoryManager gmm, uint offset, ReadOnlySpan<byte> data)
public static void DeviceWrite(this DeviceMemoryManager gmm, uint offset, ReadOnlySpan<byte> data)
{
gmm.Write((ulong)offset << 8, data);
gmm.Write(ExtendOffset(offset), data);
}
public static ulong ExtendOffset(uint offset)

View file

@ -1,6 +1,5 @@
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Nvdec.Image;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -17,9 +16,9 @@ namespace Ryujinx.Graphics.Nvdec
private readonly ConcurrentDictionary<long, NvdecDecoderContext> _contexts;
private NvdecDecoderContext _currentContext;
public NvdecDevice(MemoryManager gmm)
public NvdecDevice(DeviceMemoryManager mm)
{
_rm = new ResourceManager(gmm, new SurfaceCache(gmm));
_rm = new ResourceManager(mm, new SurfaceCache(mm));
_state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback>
{
{ nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) },

View file

@ -1,16 +1,16 @@
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Nvdec.Image;
namespace Ryujinx.Graphics.Nvdec
{
readonly struct ResourceManager
{
public MemoryManager Gmm { get; }
public DeviceMemoryManager MemoryManager { get; }
public SurfaceCache Cache { get; }
public ResourceManager(MemoryManager gmm, SurfaceCache cache)
public ResourceManager(DeviceMemoryManager mm, SurfaceCache cache)
{
Gmm = gmm;
MemoryManager = mm;
Cache = cache;
}
}

View file

@ -8,7 +8,6 @@
<ItemGroup>
<ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Device\Ryujinx.Graphics.Device.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Gpu\Ryujinx.Graphics.Gpu.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Nvdec.Vp9\Ryujinx.Graphics.Nvdec.Vp9.csproj" />
<ProjectReference Include="..\Ryujinx.Graphics.Texture\Ryujinx.Graphics.Texture.csproj" />

View file

@ -10,8 +10,8 @@ namespace Ryujinx.Graphics.Nvdec
{
public static void Decode(NvdecDecoderContext context, ResourceManager rm, ref NvdecRegisters state)
{
PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.VLDBufferSize);
PictureInfo pictureInfo = rm.MemoryManager.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
ReadOnlySpan<byte> bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.VLDBufferSize);
Decoder decoder = context.GetVp8Decoder();
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Nvdec
if (decoder.Decode(ref info, outputSurface, bitstream))
{
SurfaceWriter.Write(rm.Gmm, outputSurface, lumaOffset, chromaOffset);
SurfaceWriter.Write(rm.MemoryManager, outputSurface, lumaOffset, chromaOffset);
}
rm.Cache.Put(outputSurface);

View file

@ -1,5 +1,5 @@
using Ryujinx.Common;
using Ryujinx.Graphics.Gpu.Memory;
using Ryujinx.Graphics.Device;
using Ryujinx.Graphics.Nvdec.Image;
using Ryujinx.Graphics.Nvdec.Types.Vp9;
using Ryujinx.Graphics.Nvdec.Vp9;
@ -17,8 +17,8 @@ namespace Ryujinx.Graphics.Nvdec
public unsafe static void Decode(ResourceManager rm, ref NvdecRegisters state)
{
PictureInfo pictureInfo = rm.Gmm.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
EntropyProbs entropy = rm.Gmm.DeviceRead<EntropyProbs>(state.Vp9SetProbTabBufOffset);
PictureInfo pictureInfo = rm.MemoryManager.DeviceRead<PictureInfo>(state.SetDrvPicSetupOffset);
EntropyProbs entropy = rm.MemoryManager.DeviceRead<EntropyProbs>(state.Vp9SetProbTabBufOffset);
ISurface Rent(uint lumaOffset, uint chromaOffset, FrameSize size)
{
@ -38,19 +38,19 @@ namespace Ryujinx.Graphics.Nvdec
entropy.Convert(ref info.Entropy);
ReadOnlySpan<byte> bitstream = rm.Gmm.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize);
ReadOnlySpan<byte> bitstream = rm.MemoryManager.DeviceGetSpan(state.SetInBufBaseOffset, (int)pictureInfo.BitstreamSize);
ReadOnlySpan<Vp9MvRef> mvsIn = ReadOnlySpan<Vp9MvRef>.Empty;
if (info.UsePrevInFindMvRefs)
{
mvsIn = GetMvsInput(rm.Gmm, pictureInfo.CurrentFrameSize, state.Vp9SetColMvReadBufOffset);
mvsIn = GetMvsInput(rm.MemoryManager, pictureInfo.CurrentFrameSize, state.Vp9SetColMvReadBufOffset);
}
int miCols = BitUtils.DivRoundUp(pictureInfo.CurrentFrameSize.Width, 8);
int miRows = BitUtils.DivRoundUp(pictureInfo.CurrentFrameSize.Height, 8);
using var mvsRegion = rm.Gmm.GetWritableRegion(ExtendOffset(state.Vp9SetColMvWriteBufOffset), miRows * miCols * 16);
using var mvsRegion = rm.MemoryManager.GetWritableRegion(ExtendOffset(state.Vp9SetColMvWriteBufOffset), miRows * miCols * 16);
Span<Vp9MvRef> mvsOut = MemoryMarshal.Cast<byte, Vp9MvRef>(mvsRegion.Memory.Span);
@ -59,10 +59,10 @@ namespace Ryujinx.Graphics.Nvdec
if (_decoder.Decode(ref info, currentSurface, bitstream, mvsIn, mvsOut))
{
SurfaceWriter.Write(rm.Gmm, currentSurface, lumaOffset, chromaOffset);
SurfaceWriter.Write(rm.MemoryManager, currentSurface, lumaOffset, chromaOffset);
}
WriteBackwardUpdates(rm.Gmm, state.Vp9SetCtxCounterBufOffset, ref info.BackwardUpdateCounts);
WriteBackwardUpdates(rm.MemoryManager, state.Vp9SetCtxCounterBufOffset, ref info.BackwardUpdateCounts);
rm.Cache.Put(lastSurface);
rm.Cache.Put(goldenSurface);
@ -70,17 +70,17 @@ namespace Ryujinx.Graphics.Nvdec
rm.Cache.Put(currentSurface);
}
private static ReadOnlySpan<Vp9MvRef> GetMvsInput(MemoryManager gmm, FrameSize size, uint offset)
private static ReadOnlySpan<Vp9MvRef> GetMvsInput(DeviceMemoryManager mm, FrameSize size, uint offset)
{
int miCols = BitUtils.DivRoundUp(size.Width, 8);
int miRows = BitUtils.DivRoundUp(size.Height, 8);
return MemoryMarshal.Cast<byte, Vp9MvRef>(gmm.DeviceGetSpan(offset, miRows * miCols * 16));
return MemoryMarshal.Cast<byte, Vp9MvRef>(mm.DeviceGetSpan(offset, miRows * miCols * 16));
}
private static void WriteBackwardUpdates(MemoryManager gmm, uint offset, ref Vp9BackwardUpdates counts)
private static void WriteBackwardUpdates(DeviceMemoryManager mm, uint offset, ref Vp9BackwardUpdates counts)
{
using var backwardUpdatesRegion = gmm.GetWritableRegion(ExtendOffset(offset), Unsafe.SizeOf<BackwardUpdates>());
using var backwardUpdatesRegion = mm.GetWritableRegion(ExtendOffset(offset), Unsafe.SizeOf<BackwardUpdates>());
ref var backwardUpdates = ref MemoryMarshal.Cast<byte, BackwardUpdates>(backwardUpdatesRegion.Memory.Span)[0];