using XFESystem.Core; using Xunit; namespace XFESystem.Core.Tests; public sealed class RenderBackendSelectionTests { private static RenderBackendProbeResult Software() => new( new("CPU framebuffer", RenderAdapterKind.Software, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest), true, true, true, false, false, "Initialized framebuffer; pixel write and presentation verified."); private static RenderBackendProbeResult Gpu(RenderAdapterKind adapter, RenderBackendKind kind = RenderBackendKind.NativeGpu, RenderExecutionScope scope = RenderExecutionScope.XFESystemGuest, ushort vendor = 0x10DE) => new( new(adapter.ToString(), adapter, kind, scope, vendor), true, true, true, true, kind == RenderBackendKind.Cuda, "Actual driver/context, submission result and presentation verified by owning runtime."); [Fact] public void VerifiedDiscreteGpuIsPreferredRegardlessOfEnumerationOrder() { var discrete = Gpu(RenderAdapterKind.Discrete); var selection = RenderBackendSelection.Select([Software(), Gpu(RenderAdapterKind.Integrated), discrete]); Assert.Equal(discrete, selection.Selected); Assert.True(selection.GpuAccelerationActive); Assert.False(selection.CudaAccelerationActive); } [Fact] public void FailedDiscreteInitializationFallsBackToVerifiedIntegratedGpu() { var integrated = Gpu(RenderAdapterKind.Integrated); var failed = Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false, Evidence = "No native NVIDIA driver." }; var selection = RenderBackendSelection.Select([Software(), failed, integrated]); Assert.Equal(integrated, selection.Selected); Assert.Contains("No native NVIDIA driver.", selection.Attempts[1].Reason); } [Fact] public void HostCudaSuccessCannotEnableCudaInTheGuest() { var selection = RenderBackendSelection.Select([Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host), Software()]); Assert.Equal(Software(), selection.Selected); Assert.False(selection.GpuAccelerationActive); Assert.False(selection.CudaAccelerationActive); Assert.Contains("host hardware is not a guest backend", selection.Attempts[0].Reason); } [Fact] public void VerifiedCudaIsOnlySelectableInItsActualExecutionScope() { var host = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host); var selection = RenderBackendSelection.Select([host], RenderExecutionScope.Host); Assert.Equal(host, selection.Selected); Assert.True(selection.CudaAccelerationActive); } [Theory] [InlineData(false, true, true)] [InlineData(true, false, true)] [InlineData(true, true, false)] public void UnverifiedGpuNeverSupplantsAWorkingCpuRenderer(bool initialization, bool rendering, bool presentation) { var pending = Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = initialization, RenderSelfTestPassed = rendering, PresentationSelfTestPassed = presentation }; var selection = RenderBackendSelection.Select([pending, Software()]); Assert.Equal(Software(), selection.Selected); Assert.False(selection.GpuAccelerationActive); } [Fact] public void EnumeratedCudaAdapterWithoutCudaSubmissionIsRejected() { var cuda = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda) with { CudaSubmissionVerified = false }; var selection = RenderBackendSelection.Select([cuda, Software()]); Assert.False(selection.CudaAccelerationActive); Assert.False(selection.Attempts[0].Eligible); Assert.Contains("No CUDA kernel submission", selection.Attempts[0].Reason); } [Fact] public void CudaCannotRunOnAnAmdAdapter() { var amd = Gpu(RenderAdapterKind.Integrated, RenderBackendKind.Cuda, vendor: 0x1002); var selection = RenderBackendSelection.Select([amd, Software()]); Assert.Equal(Software(), selection.Selected); Assert.Contains("NVIDIA", selection.Attempts[0].Reason); } [Fact] public void VirtIo2DIsCpuRasterizationEvenWhenAHostGpuCompositesTheDisplay() { var virtio = Software() with { Identity = new("virtio-gpu 2D", RenderAdapterKind.Virtual, RenderBackendKind.VirtIo2D, RenderExecutionScope.XFESystemGuest) }; var selection = RenderBackendSelection.Select([virtio]); Assert.Equal(virtio, selection.Selected); Assert.False(selection.GpuAccelerationActive); Assert.False(selection.CudaAccelerationActive); Assert.False(RenderBackendSelection.Select([virtio with { RasterizationOnGpu = true }]).HasBackend); } [Fact] public void MissingEvidenceOrMissingDriverCannotInventASoftwareFallback() { Assert.False(RenderBackendSelection.Select([]).HasBackend); Assert.False(RenderBackendSelection.Select([Software() with { Evidence = "" }]).HasBackend); Assert.False(RenderBackendSelection.Select([Software() with { InitializationPassed = false }]).HasBackend); } [Fact] public void GpuLabelAloneCannotConvertACpuFramebufferToAnAccelerator() { var mislabeled = Software() with { Identity = new("RTX 5090 framebuffer", RenderAdapterKind.Discrete, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest, 0x10DE), RasterizationOnGpu = true }; var selection = RenderBackendSelection.Select([mislabeled, Software()]); Assert.Equal(Software(), selection.Selected); Assert.False(selection.GpuAccelerationActive); } private sealed class Probe(RenderBackendProbeResult result) : IRenderBackendProbe { public RenderBackendIdentity Identity => result.Identity; public int Initializations { get; private set; } public RenderBackendProbeResult InitializeAndVerify() { Initializations++; return result; } } [Fact] public void InitializationEntryPointCallsEachOwningDriverExactlyOnce() { var software = new Probe(Software()); var discrete = new Probe(Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false }); var selected = RenderBackendSelection.InitializeAndSelect([discrete, software]); Assert.Equal(1, discrete.Initializations); Assert.Equal(1, software.Initializations); Assert.Equal(Software(), selected.Selected); } private sealed class FailingProbe : IRenderBackendProbe { public RenderBackendIdentity Identity => Gpu(RenderAdapterKind.Discrete).Identity; public RenderBackendProbeResult InitializeAndVerify() => throw new InvalidOperationException("Device initialization failed."); } [Fact] public void FailedGpuDriverExceptionStillPermitsTheWorkingCpuRenderer() { var selection = RenderBackendSelection.InitializeAndSelect([new FailingProbe(), new Probe(Software())]); Assert.Equal(Software(), selection.Selected); Assert.Contains("Device initialization failed.", selection.Attempts[0].Reason); } [Fact] public void UnknownEnumsAreRejectedRatherThanGivenHigherGpuPriority() { var invalid = Gpu((RenderAdapterKind)999); Assert.False(RenderBackendSelection.Select([invalid]).HasBackend); Assert.False(RenderBackendSelection.Select([invalid with { Identity = invalid.Identity with { Adapter = RenderAdapterKind.Discrete, Backend = (RenderBackendKind)999 } }]).HasBackend); } }