using Ryujinx.Cpu.Tracking; using Ryujinx.Memory.Tracking; using System; namespace Ryujinx.Graphics.Gpu.Memory { /// /// A tracking handle for a region of GPU VA, represented by one or more tracking handles in CPU VA. /// class GpuRegionHandle : IRegionHandle { private readonly CpuRegionHandle[] _cpuRegionHandles; public bool Dirty { get { foreach (var regionHandle in _cpuRegionHandles) { if (regionHandle.Dirty) { return true; } } return false; } } public ulong Address => throw new NotSupportedException(); public ulong Size => throw new NotSupportedException(); public ulong EndAddress => throw new NotSupportedException(); /// /// Create a new GpuRegionHandle, made up of mulitple CpuRegionHandles. /// /// The CpuRegionHandles that make up this handle public GpuRegionHandle(CpuRegionHandle[] cpuRegionHandles) { _cpuRegionHandles = cpuRegionHandles; } /// /// Dispose the child handles. /// public void Dispose() { foreach (var regionHandle in _cpuRegionHandles) { regionHandle.Dispose(); } } /// /// Register an action to perform when the tracked region is read or written. /// The action is automatically removed after it runs. /// /// Action to call on read or write public void RegisterAction(RegionSignal action) { foreach (var regionHandle in _cpuRegionHandles) { regionHandle.RegisterAction(action); } } /// /// Register an action to perform when a precise access occurs (one with exact address and size). /// If the action returns true, read/write tracking are skipped. /// /// Action to call on read or write public void RegisterPreciseAction(PreciseRegionSignal action) { foreach (var regionHandle in _cpuRegionHandles) { regionHandle.RegisterPreciseAction(action); } } /// /// Consume the dirty flag for the handles, and reprotect so it can be set on the next write. /// public void Reprotect(bool asDirty = false) { foreach (var regionHandle in _cpuRegionHandles) { regionHandle.Reprotect(asDirty); } } /// /// Force the handles to be dirty, without reprotecting. /// public void ForceDirty() { foreach (var regionHandle in _cpuRegionHandles) { regionHandle.ForceDirty(); } } } }