diff --git a/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/FilePathNotificationIcon.cs b/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/FilePathNotificationIcon.cs
index 3aa712160..fe68fa7ba 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/FilePathNotificationIcon.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/FilePathNotificationIcon.cs
@@ -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;
/// If there was no texture loaded for any reason, the plugin icon will be displayed instead.
internal class FilePathNotificationIcon : INotificationIcon
{
- private readonly FileInfo fileInfo;
+ private readonly string filePath;
/// Initializes a new instance of the class.
/// The path to a .tex file inside the game resources.
- public FilePathNotificationIcon(string filePath) => this.fileInfo = new(filePath);
+ public FilePathNotificationIcon(string filePath) => this.filePath = new(filePath);
///
public bool DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color) =>
NotificationUtilities.DrawIconFrom(
minCoord,
maxCoord,
- Service.Get().GetTextureFromFile(this.fileInfo));
+ Service.Get().Shared.GetFromFile(this.filePath).GetWrapOrDefault());
///
public override bool Equals(object? obj) =>
- obj is FilePathNotificationIcon r && r.fileInfo.FullName == this.fileInfo.FullName;
+ obj is FilePathNotificationIcon r && r.filePath == this.filePath;
///
- public override int GetHashCode() => HashCode.Combine(this.GetType().GetHashCode(), this.fileInfo.FullName);
+ public override int GetHashCode() => HashCode.Combine(this.GetType().GetHashCode(), this.filePath);
///
- public override string ToString() => $"{nameof(FilePathNotificationIcon)}({this.fileInfo.FullName})";
+ public override string ToString() => $"{nameof(FilePathNotificationIcon)}({this.filePath})";
}
diff --git a/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/GamePathNotificationIcon.cs b/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/GamePathNotificationIcon.cs
index e0699e1b6..93d515ecc 100644
--- a/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/GamePathNotificationIcon.cs
+++ b/Dalamud/Interface/ImGuiNotification/Internal/NotificationIcon/GamePathNotificationIcon.cs
@@ -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
/// Initializes a new instance of the class.
/// The path to a .tex file inside the game resources.
- /// Use to get the game path from icon IDs.
public GamePathNotificationIcon(string gamePath) => this.gamePath = gamePath;
///
@@ -21,7 +19,7 @@ internal class GamePathNotificationIcon : INotificationIcon
NotificationUtilities.DrawIconFrom(
minCoord,
maxCoord,
- Service.Get().GetTextureFromGame(this.gamePath));
+ Service.Get().Shared.GetFromGame(this.gamePath).GetWrapOrDefault());
///
public override bool Equals(object? obj) => obj is GamePathNotificationIcon r && r.gamePath == this.gamePath;
diff --git a/Dalamud/Interface/Internal/DalamudInterface.cs b/Dalamud/Interface/Internal/DalamudInterface.cs
index a9e1a0b0c..da5570848 100644
--- a/Dalamud/Interface/Internal/DalamudInterface.cs
+++ b/Dalamud/Interface/Internal/DalamudInterface.cs
@@ -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;
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
index 47f0dde64..c1a44b583 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/ImGuiWidget.cs
@@ -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.Get().GetIcon(i));
+ n.IconTexture = DisposeLoggingTextureWrap.Wrap(
+ Service.Get().Shared.GetFromGameIcon(new(i)).GetWrapOrDefault());
}
}
}
diff --git a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
index 4713022e6..85b0dc00d 100644
--- a/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
+++ b/Dalamud/Interface/Internal/Windows/Data/Widgets/TexWidget.cs
@@ -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
///
public bool Ready { get; set; }
- private ITextureProvider TextureManagerForApi9 => this.textureManager!;
-
///
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? 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)
diff --git a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
index 02b5f22a5..c7456db2d 100644
--- a/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
+++ b/Dalamud/Interface/Internal/Windows/PluginInstaller/PluginInstallerWindow.cs
@@ -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;
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs b/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs
index 7e9b209cf..eee8c6e52 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.FromExistingTexture.cs
@@ -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);
- 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);
tex2D.Get()->GetDevice(device.GetAddressOf());
using var context = default(ComPtr);
device.Get()->GetImmediateContext(context.GetAddressOf());
- using var tmpTex = default(ComPtr);
- 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);
- 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));
diff --git a/Dalamud/Interface/Textures/Internal/TextureManager.cs b/Dalamud/Interface/Textures/Internal/TextureManager.cs
index 7510ec7dc..9dffc6853 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManager.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManager.cs
@@ -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;
/// Service responsible for loading and disposing ImGui texture wraps.
[ServiceManager.EarlyLoadedService]
internal sealed partial class TextureManager
- : IServiceType,
- IDisposable,
+ : IInternalDisposableService,
ITextureProvider,
ITextureSubstitutionProvider,
ITextureReadbackProvider
@@ -101,7 +101,7 @@ internal sealed partial class TextureManager
}
///
- public void Dispose()
+ void IInternalDisposableService.DisposeService()
{
if (this.disposing)
return;
@@ -221,6 +221,53 @@ internal sealed partial class TextureManager
static T? ForceNullable(T s) => s;
}
+ ///
+ 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;
+ }
+
///
bool ITextureProvider.IsDxgiFormatSupported(int dxgiFormat) =>
this.IsDxgiFormatSupported((DXGI_FORMAT)dxgiFormat);
diff --git a/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs b/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
index afdca0f31..9e7544fa2 100644
--- a/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
+++ b/Dalamud/Interface/Textures/Internal/TextureManagerPluginScoped.cs
@@ -28,9 +28,8 @@ namespace Dalamud.Interface.Textures.Internal;
[ResolveVia]
[ResolveVia]
#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
}
///
- 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})";
}
+ ///
+ 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;
+ }
+
///
public async Task CreateFromExistingTextureAsync(
IDalamudTextureWrap wrap,
diff --git a/Dalamud/Interface/Textures/RawImageSpecification.cs b/Dalamud/Interface/Textures/RawImageSpecification.cs
index e2bad7e5f..6f31cbbf7 100644
--- a/Dalamud/Interface/Textures/RawImageSpecification.cs
+++ b/Dalamud/Interface/Textures/RawImageSpecification.cs
@@ -31,6 +31,13 @@ public record struct RawImageSpecification
this.DxgiFormat = dxgiFormat;
}
+ /// Initializes a new instance of the class.
+ /// The source texture description.
+ internal RawImageSpecification(in D3D11_TEXTURE2D_DESC desc)
+ : this((int)desc.Width, (int)desc.Height, (int)desc.Format)
+ {
+ }
+
/// Initializes a new instance of the class.
/// The source texture description.
/// The pitch of the raw image in bytes.
diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs
index 58f4f3cb7..7311b0b91 100644
--- a/Dalamud/Interface/UiBuilder.cs
+++ b/Dalamud/Interface/UiBuilder.cs
@@ -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 InterfaceManagerWithSceneAsync =>
Service.GetAsync().ContinueWith(task => task.Result.Manager);
- ///
- /// Loads an image from the specified file.
- ///
- /// The full filepath to the image.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
- [Obsolete($"Use {nameof(ITextureProvider.GetFromFile)}.")]
- public IDalamudTextureWrap LoadImage(string filePath) =>
- this.scopedTextureProvider.GetFromFile(filePath).RentAsync().Result;
-
- ///
- /// Loads an image from a byte stream, such as a png downloaded into memory.
- ///
- /// A byte array containing the raw image data.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
- [Obsolete($"Use {nameof(ITextureProvider.CreateFromImageAsync)}.")]
- public IDalamudTextureWrap LoadImage(byte[] imageData) =>
- this.scopedTextureProvider.CreateFromImageAsync(imageData).Result;
-
- ///
- /// Loads an image from raw unformatted pixel data, with no type or header information. To load formatted data, use .
- ///
- /// A byte array containing the raw pixel data.
- /// The width of the image contained in .
- /// The height of the image contained in .
- /// The number of channels (bytes per pixel) of the image contained in . This should usually be 4.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [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(),
- };
-
///
/// Loads an ULD file that can load textures containing multiple icons in a single texture.
///
@@ -395,43 +348,6 @@ public sealed class UiBuilder : IDisposable
public UldWrapper LoadUld(string uldPath)
=> new(this, uldPath);
- ///
- /// Asynchronously loads an image from the specified file, when it's possible to do so.
- ///
- /// The full filepath to the image.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
- [Obsolete($"Use {nameof(ITextureProvider.GetFromFile)}.")]
- public Task LoadImageAsync(string filePath) =>
- this.scopedTextureProvider.GetFromFile(filePath).RentAsync();
-
- ///
- /// Asynchronously loads an image from a byte stream, such as a png downloaded into memory, when it's possible to do so.
- ///
- /// A byte array containing the raw image data.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
- [Obsolete($"Use {nameof(ITextureProvider.CreateFromImageAsync)}.")]
- public Task LoadImageAsync(byte[] imageData) =>
- this.scopedTextureProvider.CreateFromImageAsync(imageData);
-
- ///
- /// 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 .
- ///
- /// A byte array containing the raw pixel data.
- /// The width of the image contained in .
- /// The height of the image contained in .
- /// The number of channels (bytes per pixel) of the image contained in . This should usually be 4.
- /// A object wrapping the created image. Use inside ImGui.Image().
- [Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
- [Obsolete($"Use {nameof(ITextureProvider.CreateFromRawAsync)}.")]
- public Task LoadImageRawAsync(byte[] imageData, int width, int height, int numChannels) =>
- numChannels switch
- {
- 4 => this.scopedTextureProvider.CreateFromRawAsync(RawImageSpecification.Rgba32(width, height), imageData),
- _ => Task.FromException(new NotSupportedException()),
- };
-
///
/// Waits for UI to become available for use.
///
diff --git a/Dalamud/Plugin/Services/ITextureProvider.cs b/Dalamud/Plugin/Services/ITextureProvider.cs
index 61f400a0e..a4fa0d382 100644
--- a/Dalamud/Plugin/Services/ITextureProvider.cs
+++ b/Dalamud/Plugin/Services/ITextureProvider.cs
@@ -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;
/// .
///
///
-public partial interface ITextureProvider
+public interface ITextureProvider
{
+ /// Creates an empty texture.
+ /// Texture specifications.
+ /// Whether to support reading from CPU, while disabling reading from GPU.
+ /// Whether to support writing from CPU, while disabling writing from GPU.
+ /// Name for debug display purposes.
+ /// A new empty texture.
+ IDalamudTextureWrap CreateEmpty(
+ RawImageSpecification specs,
+ bool cpuRead,
+ bool cpuWrite,
+ string? debugName = null);
+
/// Creates a texture from the given existing texture, cropping and converting pixel format as needed.
///
/// The source texture wrap. The passed value may be disposed once this function returns,
diff --git a/Dalamud/Utility/TerraFxCom/TerraFxD3D11Extensions.cs b/Dalamud/Utility/TerraFxCom/TerraFxD3D11Extensions.cs
new file mode 100644
index 000000000..967c1eb1b
--- /dev/null
+++ b/Dalamud/Utility/TerraFxCom/TerraFxD3D11Extensions.cs
@@ -0,0 +1,65 @@
+using TerraFX.Interop.DirectX;
+using TerraFX.Interop.Windows;
+
+namespace Dalamud.Utility.TerraFxCom;
+
+/// Extension methods for D3D11 TerraFX objects.
+internal static class TerraFxD3D11Extensions
+{
+ /// Creates a 2D texture with the given descriptor.
+ /// Device to copy from and to.
+ /// Resource descriptor.
+ /// Optional initial data for the texture.
+ /// New copied texture.
+ public static unsafe ComPtr CreateTexture2D(
+ this ComPtr device,
+ D3D11_TEXTURE2D_DESC desc,
+ ComPtr copyFrom = default)
+ {
+ using var tmpTex = default(ComPtr);
+ device.Get()->CreateTexture2D(&desc, null, tmpTex.GetAddressOf()).ThrowOnError();
+
+ if (!copyFrom.IsEmpty())
+ {
+ using var context = default(ComPtr);
+ device.Get()->GetImmediateContext(context.GetAddressOf());
+ context.Get()->CopyResource((ID3D11Resource*)tmpTex.Get(), (ID3D11Resource*)copyFrom.Get());
+ }
+
+ return new(tmpTex);
+ }
+
+ /// Creates a shader resource view for a resource.
+ /// Device to create the resource view into.
+ /// Resource to create a view on.
+ /// Resource view descriptor.
+ /// Type of the resource.
+ /// New shader resource view.
+ public static unsafe ComPtr CreateShaderResourceView(
+ this ComPtr device,
+ ComPtr 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);
+ device.Get()->CreateShaderResourceView(
+ (ID3D11Resource*)resource.Get(),
+ pDesc,
+ srv.GetAddressOf())
+ .ThrowOnError();
+ return srv;
+ }
+ }
+
+ /// Gets the descriptor for a .
+ /// Texture.
+ /// Texture descriptor.
+ public static unsafe D3D11_TEXTURE2D_DESC GetDesc(this ComPtr texture)
+ {
+ var desc = default(D3D11_TEXTURE2D_DESC);
+ texture.Get()->GetDesc(&desc);
+ return desc;
+ }
+}