98 lines
3.3 KiB
C#
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;
|
|
_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, ©SRV));
|
|
_copySRV = copySRV;
|
|
}
|
|
}
|
|
}
|