using System.Numerics;
using System.Security.Cryptography;
using Vortice.Direct3D11;
using Vortice.DXGI;
using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
internal sealed partial class GalaxyGraphics
{
private ID3D11ComputeShader? originalManualExposureCs;
private ID3D11Buffer? originalExposureConstants;
private ID3D11Texture2D? originalExposureTexture;
private ID3D11ShaderResourceView? originalExposureView;
private ID3D11UnorderedAccessView? originalExposureOutput;
private GalaxyOriginalManualExposureInputs? computedManualExposureControls;
internal GalaxyOriginalExposureState OriginalExposureState {get;private set;}
internal GalaxyOriginalHistogramResult? OriginalManualExposureResult {get;private set;}
internal bool OriginalExposureReady=>originalExposureView is not null&&OriginalExposureState!=GalaxyOriginalExposureState.Uninitialized;
internal bool OriginalExposureIsToolManual=>OriginalExposureState==GalaxyOriginalExposureState.ManualComputed;
internal int OriginalExposureDispatches {get;private set;}
private unsafe void InitializeOriginalExposure(string shader)
{
var path=Path.Combine(Path.GetDirectoryName(shader)!,"GalaxyManualExposure.dxbc");
var bytes=File.ReadAllBytes(path);
if(Convert.ToHexStringLower(SHA256.HashData(bytes))!="2a564f4d25375cf4421c9271fbe34a84091a407754124f5ebe1403b915563ca7")
throw new InvalidDataException("原手动曝光计算程序校验失败。");
originalManualExposureCs=device.CreateComputeShader(bytes);
originalExposureConstants=device.CreateBuffer(128,BindFlags.ConstantBuffer);
// Original 3521DD0: six R32_FLOAT texels, initially all zero. This
// owned resource belongs to this tool view, not another game camera.
var zeros=new float[6];
fixed(float* data=zeros)
originalExposureTexture=device.CreateTexture2D(new Texture2DDescription{
Width=6,Height=1,Format=Format.R32_Float,ArraySize=1,MipLevels=1,SampleDescription=new(1,0),
Usage=ResourceUsage.Default,BindFlags=BindFlags.ShaderResource|BindFlags.UnorderedAccess},
[new SubresourceData((nint)data,24,24)]);
originalExposureView=device.CreateShaderResourceView(originalExposureTexture);
originalExposureOutput=device.CreateUnorderedAccessView(originalExposureTexture);
OriginalExposureState=GalaxyOriginalExposureState.DefaultCreated;
OriginalManualExposureResult=null;computedManualExposureControls=null;
}
// Manual exposure is scene independent. Cache only identical explicit
// controls; auto exposure will require this view's own HDR scene analysis.
private bool ComputeOriginalManualExposure(GalaxyOriginalManualExposureInputs? controls=null)
{
if(originalManualExposureCs is null||originalExposureOutput is null||originalExposureConstants is null)return false;
var input=controls??GalaxyOriginalExposure.InitialManualControls;
if(!GalaxyOriginalExposure.TryManualExposure(input,out var expected))
{
ResetOriginalExposureToDefault();return false;
}
if(OriginalExposureState==GalaxyOriginalExposureState.ManualComputed&&computedManualExposureControls==input)return true;
context.PSSetShaderResource(20,null!);
context.ClearUnorderedAccessView(originalExposureOutput,Vector4.Zero);
context.UpdateSubresource<Vector4>(GalaxyOriginalExposure.ManualConstants(input),originalExposureConstants);
context.CSSetShader(originalManualExposureCs);context.CSSetConstantBuffer(0,originalExposureConstants);
context.CSSetUnorderedAccessView(0,originalExposureOutput);context.Dispatch(1,1,1);
context.CSSetUnorderedAccessView(0,null!);context.CSSetConstantBuffer(0,null!);context.CSSetShader(null!);
computedManualExposureControls=input;OriginalManualExposureResult=expected;
OriginalExposureDispatches++;OriginalExposureState=GalaxyOriginalExposureState.ManualComputed;return true;
}
private void ResetOriginalExposureToDefault()
{
if(originalExposureOutput is null)return;
context.PSSetShaderResource(20,null!);context.ClearUnorderedAccessView(originalExposureOutput,Vector4.Zero);
OriginalExposureState=GalaxyOriginalExposureState.DefaultCreated;OriginalManualExposureResult=null;computedManualExposureControls=null;
}
private void DisposeOriginalExposure()
{
context.PSSetShaderResource(20,null!);context.CSSetUnorderedAccessView(0,null!);
originalExposureView?.Dispose();originalExposureOutput?.Dispose();originalExposureTexture?.Dispose();
originalExposureConstants?.Dispose();originalManualExposureCs?.Dispose();
originalExposureView=null;originalExposureOutput=null;originalExposureTexture=null;originalExposureConstants=null;originalManualExposureCs=null;
computedManualExposureControls=null;OriginalManualExposureResult=null;OriginalExposureState=GalaxyOriginalExposureState.Uninitialized;
}
}
using System.Numerics;
using System.Security.Cryptography;
using Vortice.Direct3D11;
using Vortice.DXGI;
using XFEEDToolBox.Core.Rendering;
namespace XFEEDToolBox.Rendering;
internal sealed partial class GalaxyGraphics
{
private ID3D11ComputeShader? originalManualExposureCs;
private ID3D11Buffer? originalExposureConstants;
private ID3D11Texture2D? originalExposureTexture;
private ID3D11ShaderResourceView? originalExposureView;
private ID3D11UnorderedAccessView? originalExposureOutput;
private GalaxyOriginalManualExposureInputs? computedManualExposureControls;
internal GalaxyOriginalExposureState OriginalExposureState {get;private set;}
internal GalaxyOriginalHistogramResult? OriginalManualExposureResult {get;private set;}
internal bool OriginalExposureReady=>originalExposureView is not null&&OriginalExposureState!=GalaxyOriginalExposureState.Uninitialized;
internal bool OriginalExposureIsToolManual=>OriginalExposureState==GalaxyOriginalExposureState.ManualComputed;
internal int OriginalExposureDispatches {get;private set;}
private unsafe void InitializeOriginalExposure(string shader)
{
var path=Path.Combine(Path.GetDirectoryName(shader)!,"GalaxyManualExposure.dxbc");
var bytes=File.ReadAllBytes(path);
if(Convert.ToHexStringLower(SHA256.HashData(bytes))!="2a564f4d25375cf4421c9271fbe34a84091a407754124f5ebe1403b915563ca7")
throw new InvalidDataException("原手动曝光计算程序校验失败。");
originalManualExposureCs=device.CreateComputeShader(bytes);
originalExposureConstants=device.CreateBuffer(128,BindFlags.ConstantBuffer);
// Original 3521DD0: six R32_FLOAT texels, initially all zero. This
// owned resource belongs to this tool view, not another game camera.
var zeros=new float[6];
fixed(float* data=zeros)
originalExposureTexture=device.CreateTexture2D(new Texture2DDescription{
Width=6,Height=1,Format=Format.R32_Float,ArraySize=1,MipLevels=1,SampleDescription=new(1,0),
Usage=ResourceUsage.Default,BindFlags=BindFlags.ShaderResource|BindFlags.UnorderedAccess},
[new SubresourceData((nint)data,24,24)]);
originalExposureView=device.CreateShaderResourceView(originalExposureTexture);
originalExposureOutput=device.CreateUnorderedAccessView(originalExposureTexture);
OriginalExposureState=GalaxyOriginalExposureState.DefaultCreated;
OriginalManualExposureResult=null;computedManualExposureControls=null;
}
// Manual exposure is scene independent. Cache only identical explicit
// controls; auto exposure will require this view's own HDR scene analysis.
private bool ComputeOriginalManualExposure(GalaxyOriginalManualExposureInputs? controls=null)
{
if(originalManualExposureCs is null||originalExposureOutput is null||originalExposureConstants is null)return false;
var input=controls??GalaxyOriginalExposure.InitialManualControls;
if(!GalaxyOriginalExposure.TryManualExposure(input,out var expected))
{
ResetOriginalExposureToDefault();return false;
}
if(OriginalExposureState==GalaxyOriginalExposureState.ManualComputed&&computedManualExposureControls==input)return true;
context.PSSetShaderResource(20,null!);
context.ClearUnorderedAccessView(originalExposureOutput,Vector4.Zero);
context.UpdateSubresource<Vector4>(GalaxyOriginalExposure.ManualConstants(input),originalExposureConstants);
context.CSSetShader(originalManualExposureCs);context.CSSetConstantBuffer(0,originalExposureConstants);
context.CSSetUnorderedAccessView(0,originalExposureOutput);context.Dispatch(1,1,1);
context.CSSetUnorderedAccessView(0,null!);context.CSSetConstantBuffer(0,null!);context.CSSetShader(null!);
computedManualExposureControls=input;OriginalManualExposureResult=expected;
OriginalExposureDispatches++;OriginalExposureState=GalaxyOriginalExposureState.ManualComputed;return true;
}
private void ResetOriginalExposureToDefault()
{
if(originalExposureOutput is null)return;
context.PSSetShaderResource(20,null!);context.ClearUnorderedAccessView(originalExposureOutput,Vector4.Zero);
OriginalExposureState=GalaxyOriginalExposureState.DefaultCreated;OriginalManualExposureResult=null;computedManualExposureControls=null;
}
private void DisposeOriginalExposure()
{
context.PSSetShaderResource(20,null!);context.CSSetUnorderedAccessView(0,null!);
originalExposureView?.Dispose();originalExposureOutput?.Dispose();originalExposureTexture?.Dispose();
originalExposureConstants?.Dispose();originalManualExposureCs?.Dispose();
originalExposureView=null;originalExposureOutput=null;originalExposureTexture=null;originalExposureConstants=null;originalManualExposureCs=null;
computedManualExposureControls=null;OriginalManualExposureResult=null;OriginalExposureState=GalaxyOriginalExposureState.Uninitialized;
}
}