mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
more
This commit is contained in:
parent
8c7771bf7d
commit
20717cce3d
13 changed files with 213 additions and 199 deletions
|
|
@ -1,7 +1,6 @@
|
|||
using System.IO;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Textures.Internal;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.Internal.NotificationIcon;
|
||||
|
||||
|
|
@ -9,26 +8,26 @@ namespace Dalamud.Interface.ImGuiNotification.Internal.NotificationIcon;
|
|||
/// <remarks>If there was no texture loaded for any reason, the plugin icon will be displayed instead.</remarks>
|
||||
internal class FilePathNotificationIcon : INotificationIcon
|
||||
{
|
||||
private readonly FileInfo fileInfo;
|
||||
private readonly string filePath;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="FilePathNotificationIcon"/> class.</summary>
|
||||
/// <param name="filePath">The path to a .tex file inside the game resources.</param>
|
||||
public FilePathNotificationIcon(string filePath) => this.fileInfo = new(filePath);
|
||||
public FilePathNotificationIcon(string filePath) => this.filePath = new(filePath);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color) =>
|
||||
NotificationUtilities.DrawIconFrom(
|
||||
minCoord,
|
||||
maxCoord,
|
||||
Service<TextureManager>.Get().GetTextureFromFile(this.fileInfo));
|
||||
Service<TextureManager>.Get().Shared.GetFromFile(this.filePath).GetWrapOrDefault());
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj) =>
|
||||
obj is FilePathNotificationIcon r && r.fileInfo.FullName == this.fileInfo.FullName;
|
||||
obj is FilePathNotificationIcon r && r.filePath == this.filePath;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode() => HashCode.Combine(this.GetType().GetHashCode(), this.fileInfo.FullName);
|
||||
public override int GetHashCode() => HashCode.Combine(this.GetType().GetHashCode(), this.filePath);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString() => $"{nameof(FilePathNotificationIcon)}({this.fileInfo.FullName})";
|
||||
public override string ToString() => $"{nameof(FilePathNotificationIcon)}({this.filePath})";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Interface.Textures.Internal;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.Internal.NotificationIcon;
|
||||
|
||||
|
|
@ -13,7 +12,6 @@ internal class GamePathNotificationIcon : INotificationIcon
|
|||
|
||||
/// <summary>Initializes a new instance of the <see cref="GamePathNotificationIcon"/> class.</summary>
|
||||
/// <param name="gamePath">The path to a .tex file inside the game resources.</param>
|
||||
/// <remarks>Use <see cref="ITextureProvider.GetIconPath"/> to get the game path from icon IDs.</remarks>
|
||||
public GamePathNotificationIcon(string gamePath) => this.gamePath = gamePath;
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -21,7 +19,7 @@ internal class GamePathNotificationIcon : INotificationIcon
|
|||
NotificationUtilities.DrawIconFrom(
|
||||
minCoord,
|
||||
maxCoord,
|
||||
Service<TextureManager>.Get().GetTextureFromGame(this.gamePath));
|
||||
Service<TextureManager>.Get().Shared.GetFromGame(this.gamePath).GetWrapOrDefault());
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object? obj) => obj is GamePathNotificationIcon r && r.gamePath == this.gamePath;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ using Dalamud.Hooking;
|
|||
using Dalamud.Interface.Animation.EasingFunctions;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.ImGuiFileDialog;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal.ManagedAsserts;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Internal.Windows;
|
||||
using Dalamud.Interface.Internal.Windows.Data;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Textures.Internal;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Storage.Assets;
|
||||
using Dalamud.Utility;
|
||||
|
|
@ -230,12 +231,14 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
break;
|
||||
case 7:
|
||||
n.SetIconTexture(
|
||||
DisposeLoggingTextureWrap.Wrap(tm.GetTextureFromGame(this.notificationTemplate.IconText)),
|
||||
DisposeLoggingTextureWrap.Wrap(
|
||||
tm.Shared.GetFromGame(this.notificationTemplate.IconText).GetWrapOrDefault()),
|
||||
this.notificationTemplate.LeaveTexturesOpen);
|
||||
break;
|
||||
case 8:
|
||||
n.SetIconTexture(
|
||||
DisposeLoggingTextureWrap.Wrap(tm.GetTextureFromFile(new(this.notificationTemplate.IconText))),
|
||||
DisposeLoggingTextureWrap.Wrap(
|
||||
tm.Shared.GetFromFile(this.notificationTemplate.IconText).GetWrapOrDefault()),
|
||||
this.notificationTemplate.LeaveTexturesOpen);
|
||||
break;
|
||||
}
|
||||
|
|
@ -306,7 +309,8 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
foreach (var n in this.notifications)
|
||||
{
|
||||
var i = (uint)Random.Shared.NextInt64(0, 200000);
|
||||
n.IconTexture = DisposeLoggingTextureWrap.Wrap(Service<TextureManager>.Get().GetIcon(i));
|
||||
n.IconTexture = DisposeLoggingTextureWrap.Wrap(
|
||||
Service<TextureManager>.Get().Shared.GetFromGameIcon(new(i)).GetWrapOrDefault());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ using System.Threading.Tasks;
|
|||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Textures;
|
||||
using Dalamud.Interface.Textures.Internal.SharedImmediateTextures;
|
||||
using Dalamud.Interface.Utility;
|
||||
|
|
@ -90,8 +91,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
/// <inheritdoc/>
|
||||
public bool Ready { get; set; }
|
||||
|
||||
private ITextureProvider TextureManagerForApi9 => this.textureManager!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Load()
|
||||
{
|
||||
|
|
@ -634,17 +633,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
ImGui.InputText("Icon ID", ref this.iconId, 32);
|
||||
ImGui.Checkbox("HQ Item", ref this.hq);
|
||||
ImGui.Checkbox("Hi-Res", ref this.hiRes);
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (ImGui.Button("Load Icon (API9)"))
|
||||
{
|
||||
var flags = ITextureProvider.IconFlags.None;
|
||||
if (this.hq)
|
||||
flags |= ITextureProvider.IconFlags.ItemHighQuality;
|
||||
if (this.hiRes)
|
||||
flags |= ITextureProvider.IconFlags.HiRes;
|
||||
this.addedTextures.Add(new(Api9: this.TextureManagerForApi9.GetIcon(uint.Parse(this.iconId), flags)));
|
||||
}
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Load Icon (Async)"))
|
||||
|
|
@ -668,11 +656,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
{
|
||||
ImGui.InputText("Tex Path", ref this.inputTexPath, 255);
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (ImGui.Button("Load Tex (API9)"))
|
||||
this.addedTextures.Add(new(Api9: this.TextureManagerForApi9.GetTextureFromGame(this.inputTexPath)));
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Load Tex (Async)"))
|
||||
this.addedTextures.Add(new(Api10: this.textureManager.Shared.GetFromGame(this.inputTexPath).RentAsync()));
|
||||
|
|
@ -688,11 +671,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
{
|
||||
ImGui.InputText("File Path", ref this.inputFilePath, 255);
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
if (ImGui.Button("Load File (API9)"))
|
||||
this.addedTextures.Add(new(Api9: this.TextureManagerForApi9.GetTextureFromFile(new(this.inputFilePath))));
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Load File (Async)"))
|
||||
this.addedTextures.Add(new(Api10: this.textureManager.Shared.GetFromFile(this.inputFilePath).RentAsync()));
|
||||
|
|
@ -929,7 +907,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
|
||||
private record TextureEntry(
|
||||
IDalamudTextureWrap? SharedResource = null,
|
||||
IDalamudTextureWrap? Api9 = null,
|
||||
Task<IDalamudTextureWrap>? Api10 = null,
|
||||
GameIconLookup? Api10ImmGameIcon = null,
|
||||
string? Api10ImmGamePath = null,
|
||||
|
|
@ -943,7 +920,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
public void Dispose()
|
||||
{
|
||||
this.SharedResource?.Dispose();
|
||||
this.Api9?.Dispose();
|
||||
_ = this.Api10?.ToContentDisposedTask();
|
||||
}
|
||||
|
||||
|
|
@ -951,8 +927,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
{
|
||||
if (this.SharedResource is not null)
|
||||
return "Unknown error";
|
||||
if (this.Api9 is not null)
|
||||
return "Unknown error";
|
||||
if (this.Api10 is not null)
|
||||
{
|
||||
return !this.Api10.IsCompleted
|
||||
|
|
@ -975,8 +949,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
{
|
||||
if (this.SharedResource is not null)
|
||||
return this.SharedResource;
|
||||
if (this.Api9 is not null)
|
||||
return this.Api9;
|
||||
if (this.Api10 is not null)
|
||||
return this.Api10.IsCompletedSuccessfully ? this.Api10.Result : null;
|
||||
if (this.Api10ImmGameIcon is not null)
|
||||
|
|
@ -1014,8 +986,6 @@ internal class TexWidget : IDataWindowWidget
|
|||
{
|
||||
if (this.SharedResource is not null)
|
||||
return $"{nameof(this.SharedResource)}: {this.SharedResource}";
|
||||
if (this.Api9 is not null)
|
||||
return $"{nameof(this.Api9)}: {this.Api9}";
|
||||
if (this.Api10 is { IsCompletedSuccessfully: true })
|
||||
return $"{nameof(this.Api10)}: {this.Api10.Result}";
|
||||
if (this.Api10 is not null)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using Dalamud.Interface.Colors;
|
|||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Textures.Internal;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Dalamud.Interface.Textures.TextureWraps.Internal;
|
|||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
using Dalamud.Utility.TerraFxCom;
|
||||
|
||||
using TerraFX.Interop.DirectX;
|
||||
using TerraFX.Interop.Windows;
|
||||
|
|
@ -62,18 +63,11 @@ internal sealed partial class TextureManager
|
|||
|
||||
unsafe
|
||||
{
|
||||
var srvDesc = new D3D11_SHADER_RESOURCE_VIEW_DESC(
|
||||
using var srv = this.device.CreateShaderResourceView(
|
||||
tex,
|
||||
D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D);
|
||||
using var srv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
this.device.Get()->CreateShaderResourceView(
|
||||
(ID3D11Resource*)tex.Get(),
|
||||
&srvDesc,
|
||||
srv.GetAddressOf())
|
||||
.ThrowOnError();
|
||||
new(tex.Get(), D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D));
|
||||
|
||||
var desc = default(D3D11_TEXTURE2D_DESC);
|
||||
tex.Get()->GetDesc(&desc);
|
||||
var desc = tex.GetDesc();
|
||||
|
||||
var outWrap = new UnknownTextureWrap(
|
||||
(IUnknown*)srv.Get(),
|
||||
|
|
@ -126,15 +120,10 @@ internal sealed partial class TextureManager
|
|||
TextureModificationArgs args = default,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
using var tex2D = wrapAux.NewTexRef();
|
||||
if (!args.IsCompleteSourceCopy(wrapAux.Desc))
|
||||
{
|
||||
using var tmp = await this.NoThrottleCreateFromExistingTextureAsync(wrapAux, args);
|
||||
unsafe
|
||||
{
|
||||
tex2D.Swap(&tmp);
|
||||
}
|
||||
}
|
||||
using var tex2D =
|
||||
args.IsCompleteSourceCopy(wrapAux.Desc)
|
||||
? wrapAux.NewTexRef()
|
||||
: await this.NoThrottleCreateFromExistingTextureAsync(wrapAux, args);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
|
|
@ -147,32 +136,29 @@ internal sealed partial class TextureManager
|
|||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
tex2D.Get()->GetDesc(&desc);
|
||||
var desc = tex2D.GetDesc();
|
||||
|
||||
using var device = default(ComPtr<ID3D11Device>);
|
||||
tex2D.Get()->GetDevice(device.GetAddressOf());
|
||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||
device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||
|
||||
using var tmpTex = default(ComPtr<ID3D11Texture2D>);
|
||||
if ((desc.CPUAccessFlags & (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ) == 0)
|
||||
{
|
||||
var tmpTexDesc = desc with
|
||||
{
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
SampleDesc = new(1, 0),
|
||||
Usage = D3D11_USAGE.D3D11_USAGE_STAGING,
|
||||
BindFlags = 0u,
|
||||
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());
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
using var tmpTex =
|
||||
(desc.CPUAccessFlags & (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ) == 0
|
||||
? device.CreateTexture2D(
|
||||
desc with
|
||||
{
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
SampleDesc = new(1, 0),
|
||||
Usage = D3D11_USAGE.D3D11_USAGE_STAGING,
|
||||
BindFlags = 0u,
|
||||
CPUAccessFlags = (uint)D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ,
|
||||
MiscFlags = 0u,
|
||||
},
|
||||
tex2D)
|
||||
: default;
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var mapWhat = (ID3D11Resource*)(tmpTex.IsEmpty() ? tex2D.Get() : tmpTex.Get());
|
||||
|
||||
|
|
@ -205,25 +191,22 @@ internal sealed partial class TextureManager
|
|||
if (args.NewHeight == 0)
|
||||
args = args with { NewHeight = (int)MathF.Round((args.Uv1Effective.Y - args.Uv0.Y) * wrapAux.Desc.Height) };
|
||||
|
||||
using var tex2DCopyTemp = default(ComPtr<ID3D11Texture2D>);
|
||||
unsafe
|
||||
{
|
||||
var tex2DCopyTempDesc = new D3D11_TEXTURE2D_DESC
|
||||
{
|
||||
Width = (uint)args.NewWidth,
|
||||
Height = (uint)args.NewHeight,
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
Format = args.Format,
|
||||
SampleDesc = new(1, 0),
|
||||
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
||||
BindFlags = (uint)(D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE |
|
||||
D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET),
|
||||
CPUAccessFlags = 0u,
|
||||
MiscFlags = 0u,
|
||||
};
|
||||
this.device.Get()->CreateTexture2D(&tex2DCopyTempDesc, null, tex2DCopyTemp.GetAddressOf()).ThrowOnError();
|
||||
}
|
||||
using var tex2DCopyTemp =
|
||||
this.device.CreateTexture2D(
|
||||
new()
|
||||
{
|
||||
Width = (uint)args.NewWidth,
|
||||
Height = (uint)args.NewHeight,
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
Format = args.Format,
|
||||
SampleDesc = new(1, 0),
|
||||
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
||||
BindFlags = (uint)(D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE |
|
||||
D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET),
|
||||
CPUAccessFlags = 0u,
|
||||
MiscFlags = 0u,
|
||||
});
|
||||
|
||||
await this.RunDuringPresent(() => DrawSourceTextureToTarget(wrapAux, args, this.SimpleDrawer, tex2DCopyTemp));
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Dalamud.Interface.Textures.TextureWraps.Internal;
|
|||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
using Dalamud.Utility.TerraFxCom;
|
||||
|
||||
using Lumina.Data;
|
||||
using Lumina.Data.Files;
|
||||
|
|
@ -24,8 +25,7 @@ namespace Dalamud.Interface.Textures.Internal;
|
|||
/// <summary>Service responsible for loading and disposing ImGui texture wraps.</summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
internal sealed partial class TextureManager
|
||||
: IServiceType,
|
||||
IDisposable,
|
||||
: IInternalDisposableService,
|
||||
ITextureProvider,
|
||||
ITextureSubstitutionProvider,
|
||||
ITextureReadbackProvider
|
||||
|
|
@ -101,7 +101,7 @@ internal sealed partial class TextureManager
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
void IInternalDisposableService.DisposeService()
|
||||
{
|
||||
if (this.disposing)
|
||||
return;
|
||||
|
|
@ -221,6 +221,53 @@ internal sealed partial class TextureManager
|
|||
static T? ForceNullable<T>(T s) => s;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public unsafe IDalamudTextureWrap CreateEmpty(
|
||||
RawImageSpecification specs,
|
||||
bool cpuRead,
|
||||
bool cpuWrite,
|
||||
string? debugName = null)
|
||||
{
|
||||
if (cpuRead && cpuWrite)
|
||||
throw new ArgumentException("cpuRead and cpuWrite cannot be set at the same time.");
|
||||
|
||||
var cpuaf = default(D3D11_CPU_ACCESS_FLAG);
|
||||
if (cpuRead)
|
||||
cpuaf |= D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_READ;
|
||||
if (cpuWrite)
|
||||
cpuaf |= D3D11_CPU_ACCESS_FLAG.D3D11_CPU_ACCESS_WRITE;
|
||||
|
||||
D3D11_USAGE usage;
|
||||
if (cpuRead)
|
||||
usage = D3D11_USAGE.D3D11_USAGE_STAGING;
|
||||
else if (cpuWrite)
|
||||
usage = D3D11_USAGE.D3D11_USAGE_DYNAMIC;
|
||||
else
|
||||
usage = D3D11_USAGE.D3D11_USAGE_DEFAULT;
|
||||
|
||||
using var texture = this.device.CreateTexture2D(
|
||||
new()
|
||||
{
|
||||
Width = (uint)specs.Width,
|
||||
Height = (uint)specs.Height,
|
||||
MipLevels = 1,
|
||||
ArraySize = 1,
|
||||
Format = specs.Format,
|
||||
SampleDesc = new(1, 0),
|
||||
Usage = usage,
|
||||
BindFlags = (uint)D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE,
|
||||
CPUAccessFlags = (uint)cpuaf,
|
||||
MiscFlags = 0,
|
||||
});
|
||||
using var view = this.device.CreateShaderResourceView(
|
||||
texture,
|
||||
new(texture, D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D));
|
||||
|
||||
var wrap = new UnknownTextureWrap((IUnknown*)view.Get(), specs.Width, specs.Height, true);
|
||||
this.BlameSetName(wrap, debugName ?? $"{nameof(this.CreateEmpty)}({specs})");
|
||||
return wrap;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
bool ITextureProvider.IsDxgiFormatSupported(int dxgiFormat) =>
|
||||
this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat);
|
||||
|
|
|
|||
|
|
@ -28,9 +28,8 @@ namespace Dalamud.Interface.Textures.Internal;
|
|||
[ResolveVia<ITextureSubstitutionProvider>]
|
||||
[ResolveVia<ITextureReadbackProvider>]
|
||||
#pragma warning restore SA1015
|
||||
internal sealed partial class TextureManagerPluginScoped
|
||||
: IServiceType,
|
||||
IDisposable,
|
||||
internal sealed class TextureManagerPluginScoped
|
||||
: IInternalDisposableService,
|
||||
ITextureProvider,
|
||||
ITextureSubstitutionProvider,
|
||||
ITextureReadbackProvider
|
||||
|
|
@ -114,7 +113,7 @@ internal sealed partial class TextureManagerPluginScoped
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
void IInternalDisposableService.DisposeService()
|
||||
{
|
||||
if (Interlocked.Exchange(ref this.managerTaskNullable, null) is not { } task)
|
||||
return;
|
||||
|
|
@ -134,6 +133,19 @@ internal sealed partial class TextureManagerPluginScoped
|
|||
: $"{nameof(TextureManagerPluginScoped)}({this.plugin.Name})";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDalamudTextureWrap CreateEmpty(
|
||||
RawImageSpecification specs,
|
||||
bool cpuRead,
|
||||
bool cpuWrite,
|
||||
string? debugName = null)
|
||||
{
|
||||
var manager = this.ManagerOrThrow;
|
||||
var textureWrap = manager.CreateEmpty(specs, cpuRead, cpuWrite, debugName);
|
||||
manager.Blame(textureWrap, this.plugin);
|
||||
return textureWrap;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<IDalamudTextureWrap> CreateFromExistingTextureAsync(
|
||||
IDalamudTextureWrap wrap,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ public record struct RawImageSpecification
|
|||
this.DxgiFormat = dxgiFormat;
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="RawImageSpecification"/> class.</summary>
|
||||
/// <param name="desc">The source texture description.</param>
|
||||
internal RawImageSpecification(in D3D11_TEXTURE2D_DESC desc)
|
||||
: this((int)desc.Width, (int)desc.Height, (int)desc.Format)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="RawImageSpecification"/> class.</summary>
|
||||
/// <param name="desc">The source texture description.</param>
|
||||
/// <param name="pitch">The pitch of the raw image in bytes.</param>
|
||||
|
|
|
|||
|
|
@ -12,16 +12,11 @@ using Dalamud.Interface.Internal;
|
|||
using Dalamud.Interface.Internal.ManagedAsserts;
|
||||
using Dalamud.Interface.ManagedFontAtlas;
|
||||
using Dalamud.Interface.ManagedFontAtlas.Internals;
|
||||
using Dalamud.Interface.Textures;
|
||||
using Dalamud.Interface.Textures.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
using ImGuiScene;
|
||||
|
||||
using Serilog;
|
||||
|
||||
using SharpDX.Direct3D11;
|
||||
|
|
@ -46,9 +41,6 @@ public sealed class UiBuilder : IDisposable
|
|||
|
||||
private readonly DisposeSafety.ScopedFinalizer scopedFinalizer = new();
|
||||
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
private readonly TextureManagerPluginScoped scopedTextureProvider;
|
||||
|
||||
private bool hasErrorWindow = false;
|
||||
private bool lastFrameUiHideState = false;
|
||||
|
||||
|
|
@ -78,8 +70,6 @@ public sealed class UiBuilder : IDisposable
|
|||
this.interfaceManager.ResizeBuffers += this.OnResizeBuffers;
|
||||
this.scopedFinalizer.Add(() => this.interfaceManager.ResizeBuffers -= this.OnResizeBuffers);
|
||||
|
||||
this.scopedFinalizer.Add(this.scopedTextureProvider = new(plugin));
|
||||
|
||||
this.FontAtlas =
|
||||
this.scopedFinalizer
|
||||
.Add(
|
||||
|
|
@ -350,43 +340,6 @@ public sealed class UiBuilder : IDisposable
|
|||
private Task<InterfaceManager> InterfaceManagerWithSceneAsync =>
|
||||
Service<InterfaceManager.InterfaceManagerWithScene>.GetAsync().ContinueWith(task => task.Result.Manager);
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from the specified file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The full filepath to the image.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.GetFromFile)}.")]
|
||||
public IDalamudTextureWrap LoadImage(string filePath) =>
|
||||
this.scopedTextureProvider.GetFromFile(filePath).RentAsync().Result;
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from a byte stream, such as a png downloaded into memory.
|
||||
/// </summary>
|
||||
/// <param name="imageData">A byte array containing the raw image data.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.CreateFromImageAsync)}.")]
|
||||
public IDalamudTextureWrap LoadImage(byte[] imageData) =>
|
||||
this.scopedTextureProvider.CreateFromImageAsync(imageData).Result;
|
||||
|
||||
/// <summary>
|
||||
/// Loads an image from raw unformatted pixel data, with no type or header information. To load formatted data, use <see cref="LoadImage(byte[])"/>.
|
||||
/// </summary>
|
||||
/// <param name="imageData">A byte array containing the raw pixel data.</param>
|
||||
/// <param name="width">The width of the image contained in <paramref name="imageData"/>.</param>
|
||||
/// <param name="height">The height of the image contained in <paramref name="imageData"/>.</param>
|
||||
/// <param name="numChannels">The number of channels (bytes per pixel) of the image contained in <paramref name="imageData"/>. This should usually be 4.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.CreateFromRaw)} or {nameof(ITextureProvider.CreateFromRawAsync)}.")]
|
||||
public IDalamudTextureWrap LoadImageRaw(byte[] imageData, int width, int height, int numChannels) =>
|
||||
numChannels switch
|
||||
{
|
||||
4 => this.scopedTextureProvider.CreateFromRaw(RawImageSpecification.Rgba32(width, height), imageData),
|
||||
_ => throw new NotSupportedException(),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Loads an ULD file that can load textures containing multiple icons in a single texture.
|
||||
/// </summary>
|
||||
|
|
@ -395,43 +348,6 @@ public sealed class UiBuilder : IDisposable
|
|||
public UldWrapper LoadUld(string uldPath)
|
||||
=> new(this, uldPath);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously loads an image from the specified file, when it's possible to do so.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The full filepath to the image.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.GetFromFile)}.")]
|
||||
public Task<IDalamudTextureWrap> LoadImageAsync(string filePath) =>
|
||||
this.scopedTextureProvider.GetFromFile(filePath).RentAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously loads an image from a byte stream, such as a png downloaded into memory, when it's possible to do so.
|
||||
/// </summary>
|
||||
/// <param name="imageData">A byte array containing the raw image data.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.CreateFromImageAsync)}.")]
|
||||
public Task<IDalamudTextureWrap> LoadImageAsync(byte[] imageData) =>
|
||||
this.scopedTextureProvider.CreateFromImageAsync(imageData);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously loads an image from raw unformatted pixel data, with no type or header information, when it's possible to do so. To load formatted data, use <see cref="LoadImage(byte[])"/>.
|
||||
/// </summary>
|
||||
/// <param name="imageData">A byte array containing the raw pixel data.</param>
|
||||
/// <param name="width">The width of the image contained in <paramref name="imageData"/>.</param>
|
||||
/// <param name="height">The height of the image contained in <paramref name="imageData"/>.</param>
|
||||
/// <param name="numChannels">The number of channels (bytes per pixel) of the image contained in <paramref name="imageData"/>. This should usually be 4.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> object wrapping the created image. Use <see cref="TextureWrap.ImGuiHandle"/> inside ImGui.Image().</returns>
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
[Obsolete($"Use {nameof(ITextureProvider.CreateFromRawAsync)}.")]
|
||||
public Task<IDalamudTextureWrap> LoadImageRawAsync(byte[] imageData, int width, int height, int numChannels) =>
|
||||
numChannels switch
|
||||
{
|
||||
4 => this.scopedTextureProvider.CreateFromRawAsync(RawImageSpecification.Rgba32(width, height), imageData),
|
||||
_ => Task.FromException<IDalamudTextureWrap>(new NotSupportedException()),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Waits for UI to become available for use.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ using System.Reflection;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||
using Dalamud.Interface.Textures;
|
||||
|
|
@ -32,8 +31,20 @@ namespace Dalamud.Plugin.Services;
|
|||
/// <see cref="TexWidget"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public partial interface ITextureProvider
|
||||
public interface ITextureProvider
|
||||
{
|
||||
/// <summary>Creates an empty texture.</summary>
|
||||
/// <param name="specs">Texture specifications.</param>
|
||||
/// <param name="cpuRead">Whether to support reading from CPU, while disabling reading from GPU.</param>
|
||||
/// <param name="cpuWrite">Whether to support writing from CPU, while disabling writing from GPU.</param>
|
||||
/// <param name="debugName">Name for debug display purposes.</param>
|
||||
/// <returns>A new empty texture.</returns>
|
||||
IDalamudTextureWrap CreateEmpty(
|
||||
RawImageSpecification specs,
|
||||
bool cpuRead,
|
||||
bool cpuWrite,
|
||||
string? debugName = null);
|
||||
|
||||
/// <summary>Creates a texture from the given existing texture, cropping and converting pixel format as needed.
|
||||
/// </summary>
|
||||
/// <param name="wrap">The source texture wrap. The passed value may be disposed once this function returns,
|
||||
|
|
|
|||
65
Dalamud/Utility/TerraFxCom/TerraFxD3D11Extensions.cs
Normal file
65
Dalamud/Utility/TerraFxCom/TerraFxD3D11Extensions.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using TerraFX.Interop.DirectX;
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
namespace Dalamud.Utility.TerraFxCom;
|
||||
|
||||
/// <summary>Extension methods for D3D11 TerraFX objects.</summary>
|
||||
internal static class TerraFxD3D11Extensions
|
||||
{
|
||||
/// <summary>Creates a 2D texture with the given descriptor.</summary>
|
||||
/// <param name="device">Device to copy from and to.</param>
|
||||
/// <param name="desc">Resource descriptor.</param>
|
||||
/// <param name="copyFrom">Optional initial data for the texture.</param>
|
||||
/// <returns>New copied texture.</returns>
|
||||
public static unsafe ComPtr<ID3D11Texture2D> CreateTexture2D(
|
||||
this ComPtr<ID3D11Device> device,
|
||||
D3D11_TEXTURE2D_DESC desc,
|
||||
ComPtr<ID3D11Texture2D> copyFrom = default)
|
||||
{
|
||||
using var tmpTex = default(ComPtr<ID3D11Texture2D>);
|
||||
device.Get()->CreateTexture2D(&desc, null, tmpTex.GetAddressOf()).ThrowOnError();
|
||||
|
||||
if (!copyFrom.IsEmpty())
|
||||
{
|
||||
using var context = default(ComPtr<ID3D11DeviceContext>);
|
||||
device.Get()->GetImmediateContext(context.GetAddressOf());
|
||||
context.Get()->CopyResource((ID3D11Resource*)tmpTex.Get(), (ID3D11Resource*)copyFrom.Get());
|
||||
}
|
||||
|
||||
return new(tmpTex);
|
||||
}
|
||||
|
||||
/// <summary>Creates a shader resource view for a resource.</summary>
|
||||
/// <param name="device">Device to create the resource view into.</param>
|
||||
/// <param name="resource">Resource to create a view on.</param>
|
||||
/// <param name="desc">Resource view descriptor.</param>
|
||||
/// <typeparam name="T">Type of the resource.</typeparam>
|
||||
/// <returns>New shader resource view.</returns>
|
||||
public static unsafe ComPtr<ID3D11ShaderResourceView> CreateShaderResourceView<T>(
|
||||
this ComPtr<ID3D11Device> device,
|
||||
ComPtr<T> resource,
|
||||
in D3D11_SHADER_RESOURCE_VIEW_DESC desc)
|
||||
where T : unmanaged, ID3D11Resource.Interface
|
||||
{
|
||||
fixed (D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc = &desc)
|
||||
{
|
||||
var srv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
device.Get()->CreateShaderResourceView(
|
||||
(ID3D11Resource*)resource.Get(),
|
||||
pDesc,
|
||||
srv.GetAddressOf())
|
||||
.ThrowOnError();
|
||||
return srv;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the descriptor for a <see cref="ID3D11Texture2D"/>.</summary>
|
||||
/// <param name="texture">Texture.</param>
|
||||
/// <returns>Texture descriptor.</returns>
|
||||
public static unsafe D3D11_TEXTURE2D_DESC GetDesc(this ComPtr<ID3D11Texture2D> texture)
|
||||
{
|
||||
var desc = default(D3D11_TEXTURE2D_DESC);
|
||||
texture.Get()->GetDesc(&desc);
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue