mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-02 13:53:40 +01:00
cleanup
This commit is contained in:
parent
5fd7457df4
commit
0a658477c6
3 changed files with 230 additions and 178 deletions
|
|
@ -1,3 +1,4 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -57,7 +58,9 @@ internal sealed partial class TextureManager
|
|||
|
||||
async Task<IDalamudTextureWrap> ImmediateLoadFunction(CancellationToken ct)
|
||||
{
|
||||
using var tex = await this.NoThrottleCreateFromExistingTextureAsync(wrap, args);
|
||||
// leaveWrapOpen is taken care from calling LoadTextureAsync
|
||||
using var wrapAux = new WrapAux(wrap, true);
|
||||
using var tex = await this.NoThrottleCreateFromExistingTextureAsync(wrapAux, args);
|
||||
|
||||
unsafe
|
||||
{
|
||||
|
|
@ -100,34 +103,19 @@ internal sealed partial class TextureManager
|
|||
bool leaveWrapOpen = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
||||
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
||||
using var wrapAux = new WrapAux(wrap, leaveWrapOpen);
|
||||
return await this.GetRawImageAsync(wrapAux, args, cancellationToken);
|
||||
}
|
||||
|
||||
unsafe
|
||||
private async Task<(RawImageSpecification Specification, byte[] RawData)> GetRawImageAsync(
|
||||
WrapAux wrapAux,
|
||||
TextureModificationArgs args = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var tex2D = wrapAux.NewTexRef();
|
||||
if (!args.IsCompleteSourceCopy(wrapAux.Desc))
|
||||
{
|
||||
fixed (Guid* piid = &IID.IID_ID3D11ShaderResourceView)
|
||||
((IUnknown*)wrap.ImGuiHandle)->QueryInterface(piid, (void**)texSrv.GetAddressOf()).ThrowOnError();
|
||||
|
||||
this.Device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||
|
||||
using (var texRes = default(ComPtr<ID3D11Resource>))
|
||||
{
|
||||
texSrv.Get()->GetResource(texRes.GetAddressOf());
|
||||
|
||||
using var tex2DTemp = default(ComPtr<ID3D11Texture2D>);
|
||||
texRes.As(&tex2DTemp).ThrowOnError();
|
||||
tex2D.Swap(&tex2DTemp);
|
||||
}
|
||||
|
||||
tex2D.Get()->GetDesc(&texDesc);
|
||||
}
|
||||
|
||||
if (!args.IsCompleteSourceCopy(texDesc))
|
||||
{
|
||||
using var tmp = await this.NoThrottleCreateFromExistingTextureAsync(wrap, args);
|
||||
using var tmp = await this.NoThrottleCreateFromExistingTextureAsync(wrapAux, args);
|
||||
unsafe
|
||||
{
|
||||
tex2D.Swap(&tmp);
|
||||
|
|
@ -136,11 +124,10 @@ internal sealed partial class TextureManager
|
|||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
return await this.interfaceManager.RunBeforeImGuiRender(
|
||||
() => ExtractMappedResource(this.Device, context, tex2D, cancellationToken));
|
||||
() => ExtractMappedResource(wrapAux, tex2D, cancellationToken));
|
||||
|
||||
static unsafe (RawImageSpecification Specification, byte[] RawData) ExtractMappedResource(
|
||||
ComPtr<ID3D11Device> device,
|
||||
ComPtr<ID3D11DeviceContext> context,
|
||||
in WrapAux wrapAux,
|
||||
ComPtr<ID3D11Texture2D> tex2D,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
|
|
@ -150,11 +137,9 @@ internal sealed partial class TextureManager
|
|||
try
|
||||
{
|
||||
using var tmpTex = default(ComPtr<ID3D11Texture2D>);
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
tex2D.Get()->GetDesc(&desc);
|
||||
if ((desc.CPUAccessFlags & (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ) == 0)
|
||||
if ((wrapAux.Desc.CPUAccessFlags & (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ) == 0)
|
||||
{
|
||||
var tmpTexDesc = desc with
|
||||
var tmpTexDesc = wrapAux.Desc with
|
||||
{
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
|
|
@ -164,15 +149,15 @@ internal sealed partial class TextureManager
|
|||
CPUAccessFlags = (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ,
|
||||
MiscFlags = 0u,
|
||||
};
|
||||
device.Get()->CreateTexture2D(&tmpTexDesc, null, tmpTex.GetAddressOf()).ThrowOnError();
|
||||
context.Get()->CopyResource((ID3D11Resource*)tmpTex.Get(), (ID3D11Resource*)tex2D.Get());
|
||||
wrapAux.DevPtr->CreateTexture2D(&tmpTexDesc, null, tmpTex.GetAddressOf()).ThrowOnError();
|
||||
wrapAux.CtxPtr->CopyResource((ID3D11Resource*)tmpTex.Get(), (ID3D11Resource*)tex2D.Get());
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
mapWhat = (ID3D11Resource*)(tmpTex.IsEmpty() ? tex2D.Get() : tmpTex.Get());
|
||||
context.Get()->Map(
|
||||
wrapAux.CtxPtr->Map(
|
||||
mapWhat,
|
||||
0,
|
||||
D3D11_MAP.D3D11_MAP_READ,
|
||||
|
|
@ -180,9 +165,9 @@ internal sealed partial class TextureManager
|
|||
&mapped).ThrowOnError();
|
||||
|
||||
var specs = new RawImageSpecification(
|
||||
(int)desc.Width,
|
||||
(int)desc.Height,
|
||||
(int)desc.Format,
|
||||
(int)wrapAux.Desc.Width,
|
||||
(int)wrapAux.Desc.Height,
|
||||
(int)wrapAux.Desc.Format,
|
||||
(int)mapped.RowPitch);
|
||||
var bytes = new Span<byte>(mapped.pData, checked((int)mapped.DepthPitch)).ToArray();
|
||||
return (specs, bytes);
|
||||
|
|
@ -190,44 +175,23 @@ internal sealed partial class TextureManager
|
|||
finally
|
||||
{
|
||||
if (mapWhat is not null)
|
||||
context.Get()->Unmap(mapWhat, 0);
|
||||
wrapAux.CtxPtr->Unmap(mapWhat, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ComPtr<ID3D11Texture2D>> NoThrottleCreateFromExistingTextureAsync(
|
||||
IDalamudTextureWrap wrap,
|
||||
WrapAux wrapAux,
|
||||
TextureModificationArgs args)
|
||||
{
|
||||
args.ThrowOnInvalidValues();
|
||||
|
||||
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
||||
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (Guid* piid = &IID.IID_ID3D11ShaderResourceView)
|
||||
((IUnknown*)wrap.ImGuiHandle)->QueryInterface(piid, (void**)texSrv.GetAddressOf()).ThrowOnError();
|
||||
|
||||
this.Device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||
|
||||
using (var texRes = default(ComPtr<ID3D11Resource>))
|
||||
{
|
||||
texSrv.Get()->GetResource(texRes.GetAddressOf());
|
||||
texRes.As(&tex2D).ThrowOnError();
|
||||
}
|
||||
|
||||
tex2D.Get()->GetDesc(&texDesc);
|
||||
}
|
||||
|
||||
if (args.Format == DXGI_FORMAT.DXGI_FORMAT_UNKNOWN)
|
||||
args = args with { Format = texDesc.Format };
|
||||
args = args with { Format = wrapAux.Desc.Format };
|
||||
if (args.NewWidth == 0)
|
||||
args = args with { NewWidth = (int)MathF.Round((args.Uv1Effective.X - args.Uv0.X) * texDesc.Width) };
|
||||
args = args with { NewWidth = (int)MathF.Round((args.Uv1Effective.X - args.Uv0.X) * wrapAux.Desc.Width) };
|
||||
if (args.NewHeight == 0)
|
||||
args = args with { NewHeight = (int)MathF.Round((args.Uv1Effective.Y - args.Uv0.Y) * texDesc.Height) };
|
||||
args = args with { NewHeight = (int)MathF.Round((args.Uv1Effective.Y - args.Uv0.Y) * wrapAux.Desc.Height) };
|
||||
|
||||
using var tex2DCopyTemp = default(ComPtr<ID3D11Texture2D>);
|
||||
unsafe
|
||||
|
|
@ -263,20 +227,120 @@ internal sealed partial class TextureManager
|
|||
&rtvCopyTempDesc,
|
||||
rtvCopyTemp.GetAddressOf()).ThrowOnError();
|
||||
|
||||
context.Get()->OMSetRenderTargets(1u, rtvCopyTemp.GetAddressOf(), null);
|
||||
wrapAux.CtxPtr->OMSetRenderTargets(1u, rtvCopyTemp.GetAddressOf(), null);
|
||||
this.SimpleDrawer.Draw(
|
||||
context.Get(),
|
||||
texSrv.Get(),
|
||||
wrapAux.CtxPtr,
|
||||
wrapAux.SrvPtr,
|
||||
args.Uv0,
|
||||
args.Uv1Effective);
|
||||
if (args.MakeOpaque)
|
||||
this.SimpleDrawer.StripAlpha(context.Get());
|
||||
this.SimpleDrawer.StripAlpha(wrapAux.CtxPtr);
|
||||
|
||||
var dummy = default(ID3D11RenderTargetView*);
|
||||
context.Get()->OMSetRenderTargets(1u, &dummy, null);
|
||||
wrapAux.CtxPtr->OMSetRenderTargets(1u, &dummy, null);
|
||||
}
|
||||
});
|
||||
|
||||
return new(tex2DCopyTemp);
|
||||
}
|
||||
|
||||
/// <summary>Auxiliary data from <see cref="IDalamudTextureWrap"/>.</summary>
|
||||
private unsafe struct WrapAux : IDisposable
|
||||
{
|
||||
public readonly D3D11_TEXTURE2D_DESC Desc;
|
||||
|
||||
private IDalamudTextureWrap? wrapToClose;
|
||||
|
||||
private ComPtr<ID3D11ShaderResourceView> srv;
|
||||
private ComPtr<ID3D11Resource> res;
|
||||
private ComPtr<ID3D11Texture2D> tex;
|
||||
private ComPtr<ID3D11Device> device;
|
||||
private ComPtr<ID3D11DeviceContext> context;
|
||||
|
||||
public WrapAux(IDalamudTextureWrap wrap, bool leaveWrapOpen)
|
||||
{
|
||||
this.wrapToClose = leaveWrapOpen ? null : wrap;
|
||||
|
||||
using var unk = new ComPtr<IUnknown>((IUnknown*)wrap.ImGuiHandle);
|
||||
|
||||
using var srvTemp = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
unk.As(&srvTemp).ThrowOnError();
|
||||
|
||||
using var resTemp = default(ComPtr<ID3D11Resource>);
|
||||
srvTemp.Get()->GetResource(resTemp.GetAddressOf());
|
||||
|
||||
using var texTemp = default(ComPtr<ID3D11Texture2D>);
|
||||
resTemp.As(&texTemp).ThrowOnError();
|
||||
|
||||
using var deviceTemp = default(ComPtr<ID3D11Device>);
|
||||
texTemp.Get()->GetDevice(deviceTemp.GetAddressOf());
|
||||
|
||||
using var contextTemp = default(ComPtr<ID3D11DeviceContext>);
|
||||
deviceTemp.Get()->GetImmediateContext(contextTemp.GetAddressOf());
|
||||
|
||||
fixed (D3D11_TEXTURE2D_DESC* pDesc = &this.Desc)
|
||||
texTemp.Get()->GetDesc(pDesc);
|
||||
|
||||
srvTemp.Swap(ref this.srv);
|
||||
resTemp.Swap(ref this.res);
|
||||
texTemp.Swap(ref this.tex);
|
||||
deviceTemp.Swap(ref this.device);
|
||||
contextTemp.Swap(ref this.context);
|
||||
}
|
||||
|
||||
public ID3D11ShaderResourceView* SrvPtr
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => this.srv.Get();
|
||||
}
|
||||
|
||||
public ID3D11Resource* ResPtr
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => this.res.Get();
|
||||
}
|
||||
|
||||
public ID3D11Texture2D* TexPtr
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => this.tex.Get();
|
||||
}
|
||||
|
||||
public ID3D11Device* DevPtr
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => this.device.Get();
|
||||
}
|
||||
|
||||
public ID3D11DeviceContext* CtxPtr
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => this.context.Get();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ComPtr<ID3D11ShaderResourceView> NewSrvRef() => new(this.srv);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ComPtr<ID3D11Resource> NewResRef() => new(this.res);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ComPtr<ID3D11Texture2D> NewTexRef() => new(this.tex);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ComPtr<ID3D11Device> NewDevRef() => new(this.device);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ComPtr<ID3D11DeviceContext> NewCtxRef() => new(this.context);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.srv.Reset();
|
||||
this.res.Reset();
|
||||
this.tex.Reset();
|
||||
this.device.Reset();
|
||||
this.context.Reset();
|
||||
Interlocked.Exchange(ref this.wrapToClose, null)?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,124 +27,131 @@ namespace Dalamud.Interface.Textures.Internal;
|
|||
internal sealed partial class TextureManager
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[SuppressMessage(
|
||||
"StyleCop.CSharp.LayoutRules",
|
||||
"SA1519:Braces should not be omitted from multi-line child statement",
|
||||
Justification = "Multiple fixed blocks")]
|
||||
public async Task SaveToStreamAsync(
|
||||
IDalamudTextureWrap wrap,
|
||||
IDalamudTextureWrap? wrap,
|
||||
Guid containerGuid,
|
||||
Stream stream,
|
||||
Stream? stream,
|
||||
IReadOnlyDictionary<string, object>? props = null,
|
||||
bool leaveWrapOpen = false,
|
||||
bool leaveStreamOpen = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||
try
|
||||
{
|
||||
if (wrap is null)
|
||||
throw new NullReferenceException($"{nameof(wrap)} cannot be null.");
|
||||
if (stream is null)
|
||||
throw new NullReferenceException($"{nameof(stream)} cannot be null.");
|
||||
|
||||
var dxgiFormat = this.GetFormatOf(wrap);
|
||||
if (!WicManager.GetCorrespondingWicPixelFormat(dxgiFormat, out _, out _))
|
||||
dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
using var istream = ManagedIStream.Create(stream, true);
|
||||
using var wrapAux = new WrapAux(wrap, true);
|
||||
|
||||
using var istream = ManagedIStream.Create(stream, leaveStreamOpen);
|
||||
var dxgiFormat =
|
||||
WicManager.GetCorrespondingWicPixelFormat(wrapAux.Desc.Format, out _, out _)
|
||||
? wrapAux.Desc.Format
|
||||
: DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
var (specs, bytes) = await this.GetRawImageAsync(
|
||||
wrap,
|
||||
new() { Format = dxgiFormat },
|
||||
true,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
var (specs, bytes) = await this.GetRawImageAsync(wrapAux, new() { Format = dxgiFormat }, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
this.Wic.SaveToStreamUsingWic(
|
||||
specs,
|
||||
bytes,
|
||||
containerGuid,
|
||||
istream,
|
||||
props,
|
||||
cancellationToken);
|
||||
await Task.Run(
|
||||
() => this.Wic.SaveToStreamUsingWic(
|
||||
specs,
|
||||
bytes,
|
||||
containerGuid,
|
||||
istream,
|
||||
props,
|
||||
cancellationToken),
|
||||
cancellationToken);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!leaveWrapOpen)
|
||||
wrap?.Dispose();
|
||||
if (!leaveStreamOpen)
|
||||
stream?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task SaveToFileAsync(
|
||||
IDalamudTextureWrap wrap,
|
||||
IDalamudTextureWrap? wrap,
|
||||
Guid containerGuid,
|
||||
string path,
|
||||
string? path,
|
||||
IReadOnlyDictionary<string, object>? props = null,
|
||||
bool leaveWrapOpen = false,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var wrapDispose = leaveWrapOpen ? null : wrap;
|
||||
var pathTemp = $"{path}.{GetCurrentThreadId():X08}{Environment.TickCount64:X16}.tmp";
|
||||
try
|
||||
{
|
||||
var dxgiFormat = this.GetFormatOf(wrap);
|
||||
if (!WicManager.GetCorrespondingWicPixelFormat(dxgiFormat, out _, out _))
|
||||
dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
if (wrap is null)
|
||||
throw new NullReferenceException($"{nameof(wrap)} cannot be null.");
|
||||
if (path is null)
|
||||
throw new NullReferenceException($"{nameof(path)} cannot be null.");
|
||||
|
||||
using var istream = TerraFxComInterfaceExtensions.CreateIStreamFromFile(
|
||||
pathTemp,
|
||||
FileMode.Create,
|
||||
FileAccess.Write,
|
||||
FileShare.None);
|
||||
|
||||
var (specs, bytes) = await this.GetRawImageAsync(
|
||||
wrap,
|
||||
new() { Format = dxgiFormat },
|
||||
true,
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
this.Wic.SaveToStreamUsingWic(
|
||||
specs,
|
||||
bytes,
|
||||
containerGuid,
|
||||
istream,
|
||||
props,
|
||||
cancellationToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
using var wrapAux = new WrapAux(wrap, true);
|
||||
var pathTemp = $"{path}.{GetCurrentThreadId():X08}{Environment.TickCount64:X16}.tmp";
|
||||
var trashfire = new List<Exception>();
|
||||
try
|
||||
{
|
||||
if (File.Exists(pathTemp))
|
||||
File.Delete(pathTemp);
|
||||
using (var istream = TerraFxComInterfaceExtensions.CreateIStreamFromFile(
|
||||
pathTemp,
|
||||
FileMode.Create,
|
||||
FileAccess.Write,
|
||||
FileShare.None))
|
||||
{
|
||||
var dxgiFormat =
|
||||
WicManager.GetCorrespondingWicPixelFormat(wrapAux.Desc.Format, out _, out _)
|
||||
? wrapAux.Desc.Format
|
||||
: DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
var (specs, bytes) = await this.GetRawImageAsync(
|
||||
wrapAux,
|
||||
new() { Format = dxgiFormat },
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await Task.Run(
|
||||
() => this.Wic.SaveToStreamUsingWic(
|
||||
specs,
|
||||
bytes,
|
||||
containerGuid,
|
||||
istream,
|
||||
props,
|
||||
cancellationToken),
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.Replace(pathTemp, path, null, true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
trashfire.Add(e);
|
||||
File.Move(pathTemp, path, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
catch (Exception e2)
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new AggregateException(
|
||||
"Failed to save the file, and failed to remove the temporary file.",
|
||||
e,
|
||||
e2);
|
||||
trashfire.Add(e);
|
||||
try
|
||||
{
|
||||
if (File.Exists(pathTemp))
|
||||
File.Delete(pathTemp);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
trashfire.Add(e2);
|
||||
}
|
||||
}
|
||||
|
||||
throw;
|
||||
throw new AggregateException($"{nameof(this.SaveToFileAsync)} error.", trashfire);
|
||||
}
|
||||
|
||||
try
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Replace(pathTemp, path, null, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
File.Move(pathTemp, path, true);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(pathTemp))
|
||||
File.Delete(pathTemp);
|
||||
}
|
||||
catch (Exception e2)
|
||||
{
|
||||
throw new AggregateException(
|
||||
"Failed to move the temporary file to the target path, and failed to remove the temporary file.",
|
||||
e,
|
||||
e2);
|
||||
}
|
||||
|
||||
throw;
|
||||
wrap?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,26 +228,6 @@ internal sealed partial class TextureManager
|
|||
}
|
||||
}
|
||||
|
||||
private unsafe DXGI_FORMAT GetFormatOf(IDalamudTextureWrap wrap)
|
||||
{
|
||||
using var texSrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||
fixed (Guid* piid = &IID.IID_ID3D11ShaderResourceView)
|
||||
((IUnknown*)wrap.ImGuiHandle)->QueryInterface(piid, (void**)texSrv.GetAddressOf()).ThrowOnError();
|
||||
|
||||
this.Device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||
|
||||
using var texRes = default(ComPtr<ID3D11Resource>);
|
||||
texSrv.Get()->GetResource(texRes.GetAddressOf());
|
||||
|
||||
using var tex2D = default(ComPtr<ID3D11Texture2D>);
|
||||
texRes.As(&tex2D).ThrowOnError();
|
||||
|
||||
var texDesc = default(D3D11_TEXTURE2D_DESC);
|
||||
tex2D.Get()->GetDesc(&texDesc);
|
||||
return texDesc.Format;
|
||||
}
|
||||
|
||||
/// <summary>A part of texture manager that uses Windows Imaging Component under the hood.</summary>
|
||||
internal sealed class WicManager : IDisposable
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ public interface ITextureReadbackProvider
|
|||
/// <returns>A task representing the save process.</returns>
|
||||
/// <remarks>
|
||||
/// <para><paramref name="wrap"/> must not be disposed until the task finishes.</para>
|
||||
/// <para>If the target file exists, it will be overwritten only if the save operation is successful.</para>
|
||||
/// <para>See the following webpages for the valid values for <paramref name="props"/> per
|
||||
/// <paramref name="containerGuid"/>.</para>
|
||||
/// <ul>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue