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

XFESystem

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

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

public enum RenderAdapterKind { Software, Virtual, Integrated, Discrete }
public enum RenderBackendKind { CpuFramebuffer, VirtIo2D, NativeGpu, Cuda }
public enum RenderExecutionScope { XFESystemGuest, Host }

/// <summary>Describes an initialized renderer, not merely an enumerated PCI adapter.</summary>
public readonly record struct RenderBackendIdentity(
    string Name, RenderAdapterKind Adapter, RenderBackendKind Backend,
    RenderExecutionScope Scope, ushort VendorId = 0);

/// <summary>
/// The probe must initialize its driver/context and verify a real rendering submission
/// and presentation path. Hardware enumeration, EDID and host CUDA DLL presence cannot
/// satisfy this contract. An unavailable probe supplies the actual failure reason.
/// </summary>
public readonly record struct RenderBackendProbeResult(
    RenderBackendIdentity Identity,
    bool InitializationPassed,
    bool RenderSelfTestPassed,
    bool PresentationSelfTestPassed,
    bool RasterizationOnGpu,
    bool CudaSubmissionVerified,
    string Evidence);

/// <summary>
/// Implemented by the owning runtime/driver, which keeps its resources alive while in use
/// and releases failed or unselected contexts. This interface does not implement a GPU driver.
/// </summary>
public interface IRenderBackendProbe
{
    RenderBackendIdentity Identity { get; }
    RenderBackendProbeResult InitializeAndVerify();
}

public readonly record struct RenderBackendAttempt(RenderBackendProbeResult Result, bool Eligible, string Reason);

public sealed record RenderBackendSelectionResult(RenderBackendProbeResult? Selected, RenderBackendAttempt[] Attempts)
{
    public bool HasBackend => Selected.HasValue;
    public bool GpuAccelerationActive => Selected is { RasterizationOnGpu: true };
    public bool CudaAccelerationActive => Selected is { Identity.Backend: RenderBackendKind.Cuda, CudaSubmissionVerified: true };
}

/// <summary>
/// Prefers a verified discrete GPU, then a verified integrated GPU, then a verified
/// virtual GPU. A working CPU rasterizer remains the fallback. Host renderers are never
/// treated as a native XFESystem renderer unless that execution scope is explicitly selected.
/// </summary>
public static class RenderBackendSelection
{
    public static RenderBackendSelectionResult Select(ReadOnlySpan<RenderBackendProbeResult> initialized,
        RenderExecutionScope scope = RenderExecutionScope.XFESystemGuest)
    {
        var attempts = new RenderBackendAttempt[initialized.Length];
        RenderBackendProbeResult? selected = null;
        int selectedRank = -1;
        for (int i = 0; i < initialized.Length; i++)
        {
            var result = initialized[i];
            string reason = RejectionReason(result, scope);
            bool eligible = reason.Length == 0;
            attempts[i] = new(result, eligible, eligible ? "Initialized render and presentation self-tests passed." : reason);
            if (!eligible) continue;
            int rank = result.RasterizationOnGpu ? 100 + (int)result.Identity.Adapter : 0;
            if (rank > selectedRank) { selected = result; selectedRank = rank; }
        }
        return new(selected, attempts);
    }

    public static RenderBackendSelectionResult InitializeAndSelect(ReadOnlySpan<IRenderBackendProbe> probes,
        RenderExecutionScope scope = RenderExecutionScope.XFESystemGuest)
    {
        var initialized = new RenderBackendProbeResult[probes.Length];
        for (int i = 0; i < probes.Length; i++)
        {
            ArgumentNullException.ThrowIfNull(probes[i]);
            var identity = probes[i].Identity;
            try
            {
                var result = probes[i].InitializeAndVerify();
                initialized[i] = result.Identity == identity ? result : new(identity, false, false, false, false, false,
                    "The probe returned an identity different from the device being initialized.");
            }
            catch (Exception exception) when (exception is not OutOfMemoryException)
            {
                initialized[i] = new(identity, false, false, false, false, false,
                    exception.GetType().Name + ": " + exception.Message);
            }
        }
        return Select(initialized, scope);
    }

    private static string RejectionReason(RenderBackendProbeResult result, RenderExecutionScope scope)
    {
        if (string.IsNullOrWhiteSpace(result.Identity.Name)) return "The renderer has no identity.";
        if (result.Identity.Adapter is not (RenderAdapterKind.Software or RenderAdapterKind.Virtual or RenderAdapterKind.Integrated or RenderAdapterKind.Discrete))
            return "Unknown adapter kind.";
        if (result.Identity.Backend is not (RenderBackendKind.CpuFramebuffer or RenderBackendKind.VirtIo2D or RenderBackendKind.NativeGpu or RenderBackendKind.Cuda))
            return "Unknown renderer backend.";
        if (result.Identity.Scope != scope) return "The renderer executes in a different environment; host hardware is not a guest backend.";
        if (!result.InitializationPassed) return "Driver or context initialization did not pass: " + result.Evidence;
        if (!result.RenderSelfTestPassed) return "No successful rendering submission self-test: " + result.Evidence;
        if (!result.PresentationSelfTestPassed) return "No successful presentation self-test: " + result.Evidence;
        if (string.IsNullOrWhiteSpace(result.Evidence)) return "The self-tests have no evidence.";
        if (result.Identity.Backend is RenderBackendKind.CpuFramebuffer or RenderBackendKind.VirtIo2D)
        {
            if (result.RasterizationOnGpu || result.CudaSubmissionVerified)
                return "CPU framebuffer and VirtIO 2D scanout do not execute a GPU rasterizer or CUDA submission.";
        }
        else if (!result.RasterizationOnGpu) return "The GPU backend has no verified GPU rasterization path.";
        if (result.RasterizationOnGpu && result.Identity.Adapter == RenderAdapterKind.Software)
            return "A software adapter cannot report GPU rasterization.";
        if (result.Identity.Backend == RenderBackendKind.Cuda)
        {
            if (result.Identity.VendorId != 0x10DE) return "CUDA requires an NVIDIA adapter.";
            if (!result.CudaSubmissionVerified) return "No CUDA kernel submission and result verification were completed.";
        }
        else if (result.CudaSubmissionVerified) return "CUDA evidence was attached to a non-CUDA backend.";
        return string.Empty;
    }
}