XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
namespace XFESystem.Gpu.Nvidia;

/// <summary>Validated GPU virtual range, not a physical address or proof of an MMU mapping.</summary>
public readonly struct NvidiaGpuRange
{
    public const ulong AddressLimit = 1UL << 57;
    public ulong Address { get; }
    public ulong Length { get; }
    public ulong End => Address + Length;

    public NvidiaGpuRange(ulong address, ulong length)
    {
        if (address == 0 || address >= AddressLimit || length == 0 || length > AddressLimit - address)
            throw new ArgumentOutOfRangeException(nameof(length), "Range must fit the published 57-bit virtual-address fields.");
        Address = address; Length = length;
    }

    public void RequireAlignment(uint alignment)
    {
        if (Address == 0 || Length == 0 || alignment == 0 || (alignment & (alignment - 1)) != 0 || (Address & (alignment - 1)) != 0)
            throw new ArgumentException("GPU range is empty or not aligned.");
    }

    public bool Overlaps(NvidiaGpuRange other) => Address < other.End && other.Address < End;
}

/// <summary>
/// Caller-owned, pinned native mapping. The caller must retain the CPU allocation,
/// GPU VA mapping, cache policy and channel ownership until channel disposal.
/// Constructing this value does not create any of those resources.
/// </summary>
public readonly struct NvidiaMappedRegion
{
    public nuint CpuAddress { get; }
    public NvidiaGpuRange Gpu { get; }
    public int Length { get; }

    public NvidiaMappedRegion(nuint cpuAddress, NvidiaGpuRange gpu, int length)
    {
        gpu.RequireAlignment(4);
        if (cpuAddress == 0 || (cpuAddress & 3) != 0 || length <= 0 ||
            (nuint)length > nuint.MaxValue - cpuAddress || (ulong)length > gpu.Length)
            throw new ArgumentOutOfRangeException(nameof(length), "CPU/GPU mapping is empty, misaligned or overflows.");
        CpuAddress = cpuAddress; Gpu = gpu; Length = length;
    }

    public bool CpuOverlaps(NvidiaMappedRegion other) =>
        CpuAddress < other.CpuAddress + (nuint)other.Length && other.CpuAddress < CpuAddress + (nuint)Length;
}