using System.Numerics; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text.Json; using Vortice.D3DCompiler; using Vortice.Direct3D; using Vortice.Direct3D11; using Vortice.DXGI; using XFEEDToolBox.Core.Rendering; using static Vortice.Direct3D11.D3D11; var output=Path.GetFullPath("artifacts/galaxy-manual-exposure-probe");Directory.CreateDirectory(output); void Require(bool condition,string message){if(!condition)throw new InvalidOperationException(message);} D3D11CreateDevice(IntPtr.Zero,DriverType.Warp,DeviceCreationFlags.None,[FeatureLevel.Level_11_0],out var device,out _,out var context).CheckError(); using var d=device;using var c=context; using var target=device.CreateTexture2D(new Texture2DDescription{Width=6,Height=1,Format=Format.R32G32B32A32_Float,ArraySize=1,MipLevels=1, SampleDescription=new(1,0),Usage=ResourceUsage.Default,BindFlags=BindFlags.UnorderedAccess}); using var uav=device.CreateUnorderedAccessView(target); using var staging=device.CreateTexture2D(new Texture2DDescription{Width=6,Height=1,Format=Format.R32G32B32A32_Float,ArraySize=1,MipLevels=1, SampleDescription=new(1,0),Usage=ResourceUsage.Staging,CPUAccessFlags=CpuAccessFlags.Read}); var sourcePath="artifacts/galaxy-query-research/power-outer-sources/background/hdr-programs/auto-exposure/cs_AnalyseLuminance_ManualExposure_Win64_SM50.dxbc"; var shaderPath="XFEEDToolBox/Assets/GalaxyExposure.hlsl";var sourceCode=File.ReadAllBytes(sourcePath); using var source=device.CreateComputeShader(sourceCode); using var translated=device.CreateComputeShader(Compiler.CompileFromFile(shaderPath,"CSOriginalManualExposure","cs_5_0").Span); using var constants=device.CreateBuffer(128,BindFlags.ConstantBuffer); float[] Draw(bool original,GalaxyOriginalManualExposureInputs input) { var values=GalaxyOriginalExposure.ManualConstants(input);unsafe{fixed(Vector4* p=values)context.UpdateSubresource(constants,0,null,(nint)p,0,0);} context.ClearUnorderedAccessView(uav,Vector4.Zero);context.CSSetShader(original?source:translated); context.CSSetConstantBuffer(0,constants);context.CSSetUnorderedAccessView(0,uav);context.Dispatch(1,1,1); context.CSSetUnorderedAccessView(0,null!);context.CopyResource(staging,target); var mapped=context.Map(staging,0,MapMode.Read);var pixels=new float[24];Marshal.Copy(mapped.DataPointer,pixels,0,24);context.Unmap(staging,0);return pixels; } // Deliberate named-control fixtures, not asserted runtime/game defaults. GalaxyOriginalManualExposureInputs[] inputs=[GalaxyOriginalExposure.InitialManualControls,new(0,1,2,0,1),new(-2,1,2,0,1),new(2,1,2,0,1),new(0,1.2f,2,0,1),new(.5f,1,1.5f,.25f,1.1f)]; var rows=new List();float maxGpu=0,maxCpu=0; foreach(var input in inputs) { Require(GalaxyOriginalExposure.TryManualExposure(input,out var cpu),"Valid explicit exposure controls rejected"); var actual=Draw(true,input);var port=Draw(false,input); Require(actual.All(float.IsFinite)&&port.All(float.IsFinite),"Nonfinite manual exposure output"); var error=actual.Zip(port,(a,b)=>Math.Abs(a-b)).Max();maxGpu=Math.Max(maxGpu,error); var cpuError=Math.Max(Math.Abs(actual[0]-cpu.LinearAdaptation),Math.Abs(actual[4]-cpu.CompensatedLuminance));maxCpu=Math.Max(maxCpu,cpuError); Require(error<.00001f&&cpuError<.00002f,"Original ManualExposure CS comparison failed"); Require(actual.Skip(8).All(v=>v==0),"Manual shader fabricated histogram samples2..5"); rows.Add(new{input,originalInitialControls=input==GalaxyOriginalExposure.InitialManualControls,actualAdaptation=actual[0],actualCompensatedLuminance=actual[4],type2Emissive=actual[4]*.125f,gpuError=error,cpuError}); } Require(!GalaxyOriginalExposure.TryManualExposure(new(0,0,0,0,0),out _),"Invalid curve was clamped into usable exposure"); Require(GalaxyOriginalExposure.DefaultHistogram.Type2EmissiveRescaling==0,"Original zero fallback became unity"); var report=new{passed=true,gameAccess=false,originalComputeShaderGpuCompared=true,originalInitialControlsGpuCompared=true,additionalExplicitSyntheticControls=true,runtimeControlsNotClaimed=true, maximumGpuError=maxGpu,maximumCpuError=maxCpu,rows,originalSha256=Convert.ToHexStringLower(SHA256.HashData(sourceCode)), productionHlslSha256=Convert.ToHexStringLower(SHA256.HashData(File.ReadAllBytes(shaderPath)))}; File.WriteAllText(Path.Combine(output,"result.json"),JsonSerializer.Serialize(report,new JsonSerializerOptions{WriteIndented=true}));Console.WriteLine(JsonSerializer.Serialize(report));