qstbak/Auspex/Auspex.Rendering.Direct3D/SceneDepthCapture.cs
2026-08-17 20:25:32 +10:00

98 lines
3.3 KiB
C#

using System;
using System.Numerics;
using System.Runtime.InteropServices;
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
using TerraFX.Interop.DirectX;
namespace Auspex.Rendering.Direct3D;
internal sealed class SceneDepthCapture : IDisposable
{
private unsafe ID3D11Texture2D* _copy;
private unsafe ID3D11ShaderResourceView* _copySRV;
private uint _copyWidth;
private uint _copyHeight;
public unsafe ID3D11ShaderResourceView* SRV => _copySRV;
public Vector2 UvScale { get; private set; } = new Vector2(1f, 1f);
public bool IsResolutionScaled { get; private set; }
public unsafe void Dispose()
{
if (_copySRV != null)
{
_copySRV->Release();
_copySRV = null;
}
if (_copy != null)
{
_copy->Release();
_copy = null;
}
GC.SuppressFinalize(this);
}
internal unsafe void Update()
{
RenderTargetManager* ptr = RenderTargetManager.Instance();
Texture* ptr2 = ((ptr != null) ? ptr->DepthStencil : null);
if (ptr2 == null || ptr2->D3D11Texture2D == null)
{
AuspexService.Log.Warning("[Auspex] SceneDepthCapture: scene depth source unavailable.");
return;
}
Device* ptr3 = Device.Instance();
IsResolutionScaled = ptr2->ActualWidth != ptr3->Width || ptr2->ActualHeight != ptr3->Height;
ID3D11Texture2D* d3D11Texture2D = (ID3D11Texture2D*)ptr2->D3D11Texture2D;
D3D11_TEXTURE2D_DESC srcDesc = default(D3D11_TEXTURE2D_DESC);
d3D11Texture2D->GetDesc(&srcDesc);
EnsureCopy(srcDesc);
ID3D11DeviceContext* ptr4 = default(ID3D11DeviceContext*);
((ID3D11Device*)ptr3->D3D11Forwarder)->GetImmediateContext(&ptr4);
ptr4->CopyResource((ID3D11Resource*)_copy, (ID3D11Resource*)d3D11Texture2D);
ptr4->Release();
UvScale = new Vector2((ptr2->AllocatedWidth != 0) ? ((float)ptr2->ActualWidth / (float)ptr2->AllocatedWidth) : 1f, (ptr2->AllocatedHeight != 0) ? ((float)ptr2->ActualHeight / (float)ptr2->AllocatedHeight) : 1f);
}
private unsafe void EnsureCopy(D3D11_TEXTURE2D_DESC srcDesc)
{
if (_copy == null || _copyWidth != srcDesc.Width || _copyHeight != srcDesc.Height)
{
if (_copySRV != null)
{
_copySRV->Release();
_copySRV = null;
}
if (_copy != null)
{
_copy->Release();
_copy = null;
}
ID3D11Device* d3D11Forwarder = (ID3D11Device*)Device.Instance()->D3D11Forwarder;
D3D11_TEXTURE2D_DESC d3D11_TEXTURE2D_DESC = srcDesc;
d3D11_TEXTURE2D_DESC.Format = DXGI_FORMAT.DXGI_FORMAT_R24G8_TYPELESS;
d3D11_TEXTURE2D_DESC.BindFlags = 8u;
ID3D11Texture2D* copy = default(ID3D11Texture2D*);
Marshal.ThrowExceptionForHR(d3D11Forwarder->CreateTexture2D(&d3D11_TEXTURE2D_DESC, null, &copy));
_copy = copy;
_copyWidth = srcDesc.Width;
_copyHeight = srcDesc.Height;
D3D11_SHADER_RESOURCE_VIEW_DESC d3D11_SHADER_RESOURCE_VIEW_DESC = new D3D11_SHADER_RESOURCE_VIEW_DESC
{
Format = DXGI_FORMAT.DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
ViewDimension = D3D_SRV_DIMENSION.D3D_SRV_DIMENSION_TEXTURE2D
};
d3D11_SHADER_RESOURCE_VIEW_DESC.Texture2D.MostDetailedMip = 0u;
d3D11_SHADER_RESOURCE_VIEW_DESC.Texture2D.MipLevels = 1u;
ID3D11ShaderResourceView* copySRV = default(ID3D11ShaderResourceView*);
Marshal.ThrowExceptionForHR(d3D11Forwarder->CreateShaderResourceView((ID3D11Resource*)_copy, &d3D11_SHADER_RESOURCE_VIEW_DESC, &copySRV));
_copySRV = copySRV;
}
}
}