diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj b/Dalamud.Boot/Dalamud.Boot.vcxproj index e0c82f25a..07c034b8f 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj @@ -158,6 +158,14 @@ + + + + + + + + @@ -187,4 +195,4 @@ - + \ No newline at end of file diff --git a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters index 8b4483684..eeb4c8ab2 100644 --- a/Dalamud.Boot/Dalamud.Boot.vcxproj.filters +++ b/Dalamud.Boot/Dalamud.Boot.vcxproj.filters @@ -17,6 +17,9 @@ {6ec5597d-e293-4d2a-a307-7444c8fac04b} + + {fff0ec42-beda-42f6-997b-953cc54d3d29} + @@ -140,6 +143,30 @@ + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + + + ReshadePlugin + diff --git a/Dalamud.Boot/dllmain.cpp b/Dalamud.Boot/dllmain.cpp index 9a741a47f..dd4fadd25 100644 --- a/Dalamud.Boot/dllmain.cpp +++ b/Dalamud.Boot/dllmain.cpp @@ -8,6 +8,14 @@ HMODULE g_hModule; HINSTANCE g_hGameInstance = GetModuleHandleW(nullptr); +bool g_bReshadeAvailable = false; + +static void(*s_pfnReshadeOverlayCallback)(void*) = nullptr; + +static void OnReshadeOverlay(reshade::api::effect_runtime *runtime) { + if (s_pfnReshadeOverlayCallback) + s_pfnReshadeOverlayCallback(reinterpret_cast(runtime->get_native())); +} DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { g_startInfo.from_envvars(); @@ -127,7 +135,7 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { if (result != 0) return result; - using custom_component_entry_point_fn = void (CORECLR_DELEGATE_CALLTYPE*)(LPVOID, HANDLE); + using custom_component_entry_point_fn = void (CORECLR_DELEGATE_CALLTYPE*)(LPVOID, HANDLE, LPVOID); const auto entrypoint_fn = reinterpret_cast(entrypoint_vfn); // ============================== VEH ======================================== // @@ -153,7 +161,7 @@ DWORD WINAPI InitializeImpl(LPVOID lpParam, HANDLE hMainThreadContinue) { // utils::wait_for_game_window(); logging::I("Initializing Dalamud..."); - entrypoint_fn(lpParam, hMainThreadContinue); + entrypoint_fn(lpParam, hMainThreadContinue, g_bReshadeAvailable ? &s_pfnReshadeOverlayCallback : nullptr); logging::I("Done!"); return 0; @@ -169,6 +177,9 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese switch (dwReason) { case DLL_PROCESS_ATTACH: g_hModule = hModule; + g_bReshadeAvailable = reshade::register_addon(hModule); + if (g_bReshadeAvailable) + reshade::register_event(&OnReshadeOverlay); break; case DLL_PROCESS_DETACH: @@ -178,7 +189,10 @@ BOOL APIENTRY DllMain(const HMODULE hModule, const DWORD dwReason, LPVOID lpRese // process is terminating; don't bother cleaning up if (lpReserved) return TRUE; - + + if (g_bReshadeAvailable) + reshade::unregister_event(&OnReshadeOverlay); + logging::update_dll_load_status(false); xivfixes::apply_all(false); diff --git a/Dalamud.Boot/pch.h b/Dalamud.Boot/pch.h index 3302a44fb..ae2fab9c6 100644 --- a/Dalamud.Boot/pch.h +++ b/Dalamud.Boot/pch.h @@ -59,6 +59,9 @@ // https://github.com/nlohmann/json #include "../lib/nlohmann-json/json.hpp" +// https://github.com/crosire/reshade/tree/main/include +#include "../lib/reshade/include/reshade.hpp" + #include "unicode.h" // Commonly used macros @@ -67,6 +70,7 @@ // Global variables extern HMODULE g_hModule; extern HINSTANCE g_hGameInstance; +extern bool g_bReshadeAvailable; extern std::optional g_clr; #endif //PCH_H diff --git a/Dalamud.Boot/rewrite_entrypoint.cpp b/Dalamud.Boot/rewrite_entrypoint.cpp index 85a3a950b..04f68ec51 100644 --- a/Dalamud.Boot/rewrite_entrypoint.cpp +++ b/Dalamud.Boot/rewrite_entrypoint.cpp @@ -368,7 +368,8 @@ DllExport void WINAPI RewrittenEntryPoint(RewrittenEntryPointParameters& params) loadInfo = params.pLoadInfo; } - InitializeImpl(&loadInfo[0], params.hMainThreadContinue); + if (const auto err = InitializeImpl(&loadInfo[0], params.hMainThreadContinue)) + throw std::exception(std::format("{:08X}", err).c_str()); return 0; } catch (const std::exception& e) { MessageBoxA(nullptr, std::format("Failed to load Dalamud.\n\nError: {}", e.what()).c_str(), "Dalamud.Boot", MB_OK | MB_ICONERROR); diff --git a/Dalamud/Game/Internal/DXGI/Definitions/ID3D11DeviceVtbl.cs b/Dalamud/ComInterfaceVTables/ID3D11DeviceVtbl.cs similarity index 98% rename from Dalamud/Game/Internal/DXGI/Definitions/ID3D11DeviceVtbl.cs rename to Dalamud/ComInterfaceVTables/ID3D11DeviceVtbl.cs index 4bd369dd3..34d25919a 100644 --- a/Dalamud/Game/Internal/DXGI/Definitions/ID3D11DeviceVtbl.cs +++ b/Dalamud/ComInterfaceVTables/ID3D11DeviceVtbl.cs @@ -1,8 +1,9 @@ -namespace Dalamud.Game.Internal.DXGI.Definitions; +namespace Dalamud.ComInterfaceVTables; /// /// Contains a full list of ID3D11Device functions to be used as an indexer into the DirectX Virtual Function Table entries. /// +// ReSharper disable once InconsistentNaming internal enum ID3D11DeviceVtbl { // IUnknown diff --git a/Dalamud/Game/Internal/DXGI/Definitions/IDXGISwapChainVtbl.cs b/Dalamud/ComInterfaceVTables/IDXGISwapChainVtbl.cs similarity index 96% rename from Dalamud/Game/Internal/DXGI/Definitions/IDXGISwapChainVtbl.cs rename to Dalamud/ComInterfaceVTables/IDXGISwapChainVtbl.cs index 4bcb6fb72..fd8f6773c 100644 --- a/Dalamud/Game/Internal/DXGI/Definitions/IDXGISwapChainVtbl.cs +++ b/Dalamud/ComInterfaceVTables/IDXGISwapChainVtbl.cs @@ -1,9 +1,10 @@ -namespace Dalamud.Game.Internal.DXGI.Definitions; +namespace Dalamud.ComInterfaceVTables; /// /// Contains a full list of IDXGISwapChain functions to be used as an indexer into the SwapChain Virtual Function Table /// entries. /// +// ReSharper disable once InconsistentNaming internal enum IDXGISwapChainVtbl { // IUnknown diff --git a/Dalamud/EntryPoint.cs b/Dalamud/EntryPoint.cs index 1975505a8..6b4f7a8d1 100644 --- a/Dalamud/EntryPoint.cs +++ b/Dalamud/EntryPoint.cs @@ -25,19 +25,26 @@ namespace Dalamud; /// /// The main entrypoint for the Dalamud system. /// -public sealed class EntryPoint +public static class EntryPoint { /// /// Log level switch for runtime log level change. /// public static readonly LoggingLevelSwitch LogLevelSwitch = new(LogEventLevel.Verbose); + /// + /// Pointer to function pointer that will be called upon Reshade's Present callback. + /// The value is set to null if Reshade is not detected. + /// + private static unsafe void** reshadePresentCallbackPtrPtr; + /// /// A delegate used during initialization of the CLR from Dalamud.Boot. /// /// Pointer to a serialized data. /// Event used to signal the main thread to continue. - public delegate void InitDelegate(IntPtr infoPtr, IntPtr mainThreadContinueEvent); + /// Pointer to function pointer that will be called upon Reshade's Present callback. + public delegate void InitDelegate(IntPtr infoPtr, IntPtr mainThreadContinueEvent, IntPtr externalPresentDetour); /// /// A delegate used from VEH handler on exception which CoreCLR will fast fail by default. @@ -50,10 +57,15 @@ public sealed class EntryPoint /// /// Pointer to a serialized data. /// Event used to signal the main thread to continue. - public static void Initialize(IntPtr infoPtr, IntPtr mainThreadContinueEvent) + /// Pointer to function pointer that will be called upon Reshade's Present callback. + public static void Initialize(IntPtr infoPtr, IntPtr mainThreadContinueEvent, IntPtr externalPresentDetour) { var infoStr = Marshal.PtrToStringUTF8(infoPtr)!; var info = JsonConvert.DeserializeObject(infoStr)!; + unsafe + { + reshadePresentCallbackPtrPtr = (void**)externalPresentDetour; + } if ((info.BootWaitMessageBox & 4) != 0) MessageBoxW(IntPtr.Zero, "Press OK to continue (BeforeDalamudConstruct)", "Dalamud Boot", MessageBoxType.Ok); @@ -61,6 +73,19 @@ public sealed class EntryPoint new Thread(() => RunThread(info, mainThreadContinueEvent)).Start(); } + /// + /// Attempt to register a callback for Reshade Present. + /// + /// Pointer to the callback function. + /// Whether the operation has been successful and Reshade will use this feature. + public static unsafe bool TryRegisterReshadePresentCallback(nint ptr) + { + if (reshadePresentCallbackPtrPtr == null) + return false; + *reshadePresentCallbackPtrPtr = (void*)ptr; + return true; + } + /// /// Returns stack trace. /// @@ -272,7 +297,7 @@ public sealed class EntryPoint // ignored } - const MessageBoxType flags = NativeFunctions.MessageBoxType.YesNo | NativeFunctions.MessageBoxType.IconError | NativeFunctions.MessageBoxType.SystemModal; + const MessageBoxType flags = MessageBoxType.YesNo | MessageBoxType.IconError | MessageBoxType.SystemModal; var result = MessageBoxW( Process.GetCurrentProcess().MainWindowHandle, $"An internal error in a Dalamud plugin occurred.\nThe game must close.\n\n{ex.GetType().Name}\n{info}\n\n{pluginInfo}More information has been recorded separately{supportText}.\n\nDo you want to disable all plugins the next time you start the game?", diff --git a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs b/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs deleted file mode 100644 index 867119be5..000000000 --- a/Dalamud/Game/Internal/DXGI/ISwapChainAddressResolver.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Dalamud.Game.Internal.DXGI; - -/// -/// An interface binding for the address resolvers that attempt to find native D3D11 methods. -/// -public interface ISwapChainAddressResolver -{ - /// - /// Gets or sets the address of the native D3D11.Present method. - /// - IntPtr Present { get; set; } - - /// - /// Gets or sets the address of the native D3D11.ResizeBuffers method. - /// - IntPtr ResizeBuffers { get; set; } -} diff --git a/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs deleted file mode 100644 index ad79dff9f..000000000 --- a/Dalamud/Game/Internal/DXGI/SwapChainSigResolver.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; - -using Serilog; - -namespace Dalamud.Game.Internal.DXGI; - -/// -/// The address resolver for native D3D11 methods to facilitate displaying the Dalamud UI. -/// -[Obsolete("This has been deprecated in favor of the VTable resolver.")] -public sealed class SwapChainSigResolver : BaseAddressResolver, ISwapChainAddressResolver -{ - /// - public IntPtr Present { get; set; } - - /// - public IntPtr ResizeBuffers { get; set; } - - /// - protected override void Setup64Bit(SigScanner sig) - { - var module = Process.GetCurrentProcess().Modules.Cast().First(m => m.ModuleName == "dxgi.dll"); - - Log.Debug($"Found DXGI: 0x{module.BaseAddress.ToInt64():X}"); - - var scanner = new SigScanner(module); - - // This(code after the function head - offset of it) was picked to avoid running into issues with other hooks being installed into this function. - this.Present = scanner.ScanModule("41 8B F0 8B FA 89 54 24 ?? 48 8B D9 48 89 4D ?? C6 44 24 ?? 00") - 0x37; - - this.ResizeBuffers = scanner.ScanModule("48 8B C4 55 41 54 41 55 41 56 41 57 48 8D 68 B1 48 81 EC ?? ?? ?? ?? 48 C7 45 ?? ?? ?? ?? ?? 48 89 58 10 48 89 70 18 48 89 78 20 45 8B F9 45 8B E0 44 8B EA 48 8B F9 8B 45 7F 89 44 24 30 8B 75 77 89 74 24 28 44 89 4C 24"); - } -} diff --git a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs b/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs deleted file mode 100644 index 6df67409d..000000000 --- a/Dalamud/Game/Internal/DXGI/SwapChainVtableResolver.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.InteropServices; - -using Dalamud.Game.Internal.DXGI.Definitions; -using Dalamud.Utility; -using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel; -using Serilog; - -namespace Dalamud.Game.Internal.DXGI; - -/// -/// This class attempts to determine the D3D11 SwapChain vtable addresses via instantiating a new form and inspecting it. -/// -/// -/// If the normal signature based method of resolution fails, this is the backup. -/// -public class SwapChainVtableResolver : BaseAddressResolver, ISwapChainAddressResolver -{ - public static readonly int NumDxgiSwapChainMethods = Enum.GetValues(typeof(IDXGISwapChainVtbl)).Length; - - /// - public IntPtr Present { get; set; } - - /// - public IntPtr ResizeBuffers { get; set; } - - /// - /// Gets or sets the pointer to DxgiSwapChain. - /// - public IntPtr DxgiSwapChain { get; set; } - - /// - /// Gets a value indicating whether or not ReShade is loaded/used. - /// - public bool IsReshade { get; private set; } - - /// - protected override unsafe void Setup64Bit(SigScanner sig) - { - var kernelDev = Util.NotNull(Device.Instance(), "Device.Instance()"); - var swapChain = Util.NotNull(kernelDev->SwapChain, "KernelDevice->SwapChain"); - var dxgiSwapChain = Util.NotNull(swapChain->DXGISwapChain, "SwapChain->DXGISwapChain"); - - this.DxgiSwapChain = (nint)dxgiSwapChain; - var scVtbl = GetVTblAddresses(this.DxgiSwapChain, NumDxgiSwapChainMethods); - - this.Present = scVtbl[(int)IDXGISwapChainVtbl.Present]; - - var modules = Process.GetCurrentProcess().Modules; - foreach (ProcessModule processModule in modules) - { - if (processModule.FileName != null && processModule.FileName.EndsWith("game\\dxgi.dll")) - { - var fileInfo = FileVersionInfo.GetVersionInfo(processModule.FileName); - - if (fileInfo.FileDescription == null) - break; - - if (!fileInfo.FileDescription.Contains("GShade") && !fileInfo.FileDescription.Contains("ReShade")) - break; - - // reshade master@4232872 RVA - // var p = processModule.BaseAddress + 0x82C7E0; // DXGISwapChain::Present - // var p = processModule.BaseAddress + 0x82FAC0; // DXGISwapChain::runtime_present - - // DXGISwapChain::handle_device_loss => DXGISwapChain::Present => DXGISwapChain::runtime_present - - var scanner = new SigScanner(processModule); - var runtimePresentSig = "F6 C2 01 0F 85 ?? ?? ?? ??"; - - try - { - // Looks like this sig only works for GShade 4 - if (fileInfo.FileDescription?.Contains("GShade 4.") == true) - { - Log.Verbose("Hooking present for GShade 4"); - runtimePresentSig = "E8 ?? ?? ?? ?? 45 0F B6 5E ??"; - } - } - catch (Exception ex) - { - Log.Error(ex, "Failed to get reshade version info - falling back to default DXGISwapChain::runtime_present signature"); - } - - try - { - var p = scanner.ScanText(runtimePresentSig); - Log.Information($"ReShade DLL: {processModule.FileName} with DXGISwapChain::runtime_present at {p:X}"); - - this.Present = p; - this.IsReshade = true; - break; - } - catch (Exception ex) - { - Log.Error(ex, "Could not find reshade DXGISwapChain::runtime_present offset!"); - } - } - } - - this.ResizeBuffers = scVtbl[(int)IDXGISwapChainVtbl.ResizeBuffers]; - } - - private static List GetVTblAddresses(IntPtr pointer, int numberOfMethods) - { - return GetVTblAddresses(pointer, 0, numberOfMethods); - } - - private static List GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods) - { - var vtblAddresses = new List(); - var vTable = Marshal.ReadIntPtr(pointer); - for (var i = startIndex; i < startIndex + numberOfMethods; i++) - vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes - - return vtblAddresses; - } -} diff --git a/Dalamud/Hooking/ObjectVTableHook.cs b/Dalamud/Hooking/ObjectVTableHook.cs index 4ace5602a..aed39d55a 100644 --- a/Dalamud/Hooking/ObjectVTableHook.cs +++ b/Dalamud/Hooking/ObjectVTableHook.cs @@ -6,7 +6,7 @@ namespace Dalamud.Hooking; /// /// Manages a hook that works by replacing the vtable of target object. /// -public sealed unsafe class ObjectVTableHook : IDisposable +public unsafe class ObjectVTableHook : IDisposable { private readonly nint** ppVtbl; private readonly int numMethods; @@ -33,6 +33,16 @@ public sealed unsafe class ObjectVTableHook : IDisposable this.VtblOriginal.CopyTo(this.VtblOverriden); } + /// + /// Initializes a new instance of the class. + /// + /// Address to vtable. Usually the address of the object itself. + /// Number of methods in this vtable. + public ObjectVTableHook(void* ppVtbl, int numMethods) + : this((nint)ppVtbl, numMethods) + { + } + /// /// Finalizes an instance of the class. /// @@ -123,6 +133,20 @@ public sealed unsafe class ObjectVTableHook : IDisposable where T : Delegate => this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate); + /// + /// Sets a method in vtable to the given delegate. + /// + /// The method index. + /// Detour delegate. + /// Original method delegate. + /// Type of delegate. + public void SetVtableEntry(int methodIndex, T detourDelegate, out T originalMethodDelegate) + where T : Delegate + { + originalMethodDelegate = this.GetOriginalMethodDelegate(methodIndex); + this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate); + } + private void EnsureMethodIndex(int methodIndex) { if (methodIndex < 0 || methodIndex >= this.numMethods) diff --git a/Dalamud/Hooking/ObjectVTableHook{TVTable}.cs b/Dalamud/Hooking/ObjectVTableHook{TVTable}.cs new file mode 100644 index 000000000..118914fa0 --- /dev/null +++ b/Dalamud/Hooking/ObjectVTableHook{TVTable}.cs @@ -0,0 +1,85 @@ +using System; +using System.Runtime.InteropServices; + +namespace Dalamud.Hooking; + +/// +/// Typed version of . +/// +/// Type of VTable enum. +public unsafe class ObjectVTableHook : ObjectVTableHook + where TVTableEnum : unmanaged, Enum +{ + /// + /// Initializes a new instance of the class. + /// + /// Address to vtable. Usually the address of the object itself. + public ObjectVTableHook(TVTableEnum** ppVtbl) + : base(ppVtbl, Enum.GetValues(typeof(TVTableEnum)).Length) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Address to vtable. Usually the address of the object itself. + public ObjectVTableHook(void* ppVtbl) + : base(ppVtbl, Enum.GetValues(typeof(TVTableEnum)).Length) + { + } + + /// + /// Gets the original method address of the given method index. + /// + /// The method index. + /// Address of the original method. + public nint GetOriginalMethodAddress(TVTableEnum methodIndex) => + this.GetOriginalMethodAddress((int)(object)methodIndex); + + /// + /// Gets the original method of the given method index, as a delegate of given type. + /// + /// The method index. + /// Type of delegate. + /// Delegate to the original method. + public T GetOriginalMethodDelegate(TVTableEnum methodIndex) + where T : Delegate + => this.GetOriginalMethodDelegate((int)(object)methodIndex); + + /// + /// Resets a method to the original function. + /// + /// The method index. + public void ResetVtableEntry(TVTableEnum methodIndex) + => this.ResetVtableEntry((int)(object)methodIndex); + + /// + /// Sets a method in vtable to the given address of function. + /// + /// The method index. + /// Address of the detour function. + /// Additional reference to keep in memory. + public void SetVtableEntry(TVTableEnum methodIndex, nint pfn, object? refkeep) + => this.SetVtableEntry((int)(object)methodIndex, pfn, refkeep); + + /// + /// Sets a method in vtable to the given delegate. + /// + /// The method index. + /// Detour delegate. + /// Type of delegate. + public void SetVtableEntry(TVTableEnum methodIndex, T detourDelegate) + where T : Delegate => + this.SetVtableEntry(methodIndex, Marshal.GetFunctionPointerForDelegate(detourDelegate), detourDelegate); + + /// + /// Sets a method in vtable to the given delegate. + /// + /// The method index. + /// Detour delegate. + /// Original method delegate. + /// Type of delegate. + public void SetVtableEntry(TVTableEnum methodIndex, T detourDelegate, out T originalMethodDelegate) + where T : Delegate + => this.SetVtableEntry((int)(object)methodIndex, detourDelegate, out originalMethodDelegate); +} diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index 4ceb51b62..571c3d693 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -8,13 +8,12 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading; +using Dalamud.ComInterfaceVTables; using Dalamud.Configuration.Internal; using Dalamud.Game; using Dalamud.Game.ClientState.GamePad; using Dalamud.Game.ClientState.Keys; using Dalamud.Game.Gui.Internal; -using Dalamud.Game.Internal.DXGI; -using Dalamud.Game.Internal.DXGI.Definitions; using Dalamud.Hooking; using Dalamud.Interface.GameFonts; using Dalamud.Interface.Internal.ManagedAsserts; @@ -25,6 +24,7 @@ using Dalamud.Utility; using Dalamud.Utility.Timing; using ImGuiNET; using ImGuiScene; +using JetBrains.Annotations; using PInvoke; using Serilog; @@ -65,18 +65,22 @@ internal class InterfaceManager : IDisposable, IServiceType private readonly SigScanner sigScanner = Service.Get(); private readonly ManualResetEvent fontBuildSignal; - private readonly SwapChainVtableResolver address; private readonly Hook dispatchMessageWHook; private readonly Hook setCursorHook; - private Hook processMessageHook; + private readonly Hook processMessageHook; private RawDX11Scene? scene; - private ObjectVTableHook? swapChainHook; + private ObjectVTableHook? swapChainHook; + + // For handling the case where ReShade is being used. + // Marked UsedImplicitly to keep refcount for delegate so that the function pointer remains valid. + [UsedImplicitly] + private PresentCoreDelegate? presentCoreDelegate; // Use these instead of querying for functions inside the above, // since we behave differently if ReShade or stuff are detected. - private PresentDelegate presentOriginal; - private ResizeBuffersDelegate resizeBuffersOriginal; + private PresentDelegate? presentOriginal; + private ResizeBuffersDelegate? resizeBuffersOriginal; // can't access imgui IO before first present call private bool lastWantCapture = false; @@ -91,12 +95,18 @@ internal class InterfaceManager : IDisposable, IServiceType this.setCursorHook = Hook.FromImport( null, "user32.dll", "SetCursor", 0, this.SetCursorDetour); - this.fontBuildSignal = new ManualResetEvent(false); - this.address = new SwapChainVtableResolver(); + var wndProcAddress = this.sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8"); + Log.Information($"WndProc address 0x{wndProcAddress.ToInt64():X}"); + this.processMessageHook = Hook.FromAddress(wndProcAddress, this.ProcessMessageDetour); + + this.fontBuildSignal = new(false); this.QueueHookResolution(); } + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + private delegate void PresentCoreDelegate(IntPtr swapChain); + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] private delegate IntPtr PresentDelegate(IntPtr swapChain, uint syncInterval, uint presentFlags); @@ -115,22 +125,22 @@ internal class InterfaceManager : IDisposable, IServiceType /// /// This event gets called each frame to facilitate ImGui drawing. /// - public event RawDX11Scene.BuildUIDelegate Draw; + public event RawDX11Scene.BuildUIDelegate? Draw; /// /// This event gets called when ResizeBuffers is called. /// - public event Action ResizeBuffers; + public event Action? ResizeBuffers; /// /// Gets or sets an action that is executed right before fonts are rebuilt. /// - public event Action BuildFonts; + public event Action? BuildFonts; /// /// Gets or sets an action that is executed right after fonts are rebuilt. /// - public event Action AfterBuildFonts; + public event Action? AfterBuildFonts; /// /// Gets the default ImGui font. @@ -230,7 +240,7 @@ internal class InterfaceManager : IDisposable, IServiceType { this.setCursorHook.Dispose(); this.dispatchMessageWHook.Dispose(); - this.processMessageHook?.Dispose(); + this.processMessageHook.Dispose(); }).Wait(); this.scene?.Dispose(); @@ -357,9 +367,9 @@ internal class InterfaceManager : IDisposable, IServiceType ImFontPtr foundFont = null; unsafe { - for (int i = 0, i_ = fonts.Size; i < i_; i++) + for (int i = 0, iTo = fonts.Size; i < iTo; i++) { - if (!this.glyphRequests.Any(x => x.FontInternal.NativePtr == fonts[i].NativePtr)) + if (this.glyphRequests.All(x => x.FontInternal.NativePtr != fonts[i].NativePtr)) continue; allContained = true; @@ -462,8 +472,8 @@ internal class InterfaceManager : IDisposable, IServiceType if (this.GameWindowHandle == nint.Zero) return; - int value = enabled ? 1 : 0; - var hr = NativeFunctions.DwmSetWindowAttribute( + var value = enabled ? 1 : 0; + _ = NativeFunctions.DwmSetWindowAttribute( this.GameWindowHandle, NativeFunctions.DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref value, @@ -482,14 +492,14 @@ internal class InterfaceManager : IDisposable, IServiceType { try { - newScene = new RawDX11Scene(swapChain); + newScene = new(swapChain); } catch (DllNotFoundException ex) { Service.ProvideException(ex); Log.Error(ex, "Could not load ImGui dependencies."); - var res = PInvoke.User32.MessageBox( + var res = User32.MessageBox( IntPtr.Zero, "Dalamud plugins require the Microsoft Visual C++ Redistributable to be installed.\nPlease install the runtime from the official Microsoft website or disable Dalamud.\n\nDo you want to download the redistributable now?", "Dalamud Error", @@ -514,14 +524,14 @@ internal class InterfaceManager : IDisposable, IServiceType var startInfo = Service.Get(); var configuration = Service.Get(); - var iniFileInfo = new FileInfo(Path.Combine(Path.GetDirectoryName(startInfo.ConfigurationPath), "dalamudUI.ini")); + var iniFileInfo = new FileInfo(Path.Combine(Path.GetDirectoryName(startInfo.ConfigurationPath)!, "dalamudUI.ini")); try { if (iniFileInfo.Length > 1200000) { Log.Warning("dalamudUI.ini was over 1mb, deleting"); - iniFileInfo.CopyTo(Path.Combine(iniFileInfo.DirectoryName, $"dalamudUI-{DateTimeOffset.Now.ToUnixTimeSeconds()}.ini")); + iniFileInfo.CopyTo(Path.Combine(iniFileInfo.DirectoryName!, $"dalamudUI-{DateTimeOffset.Now.ToUnixTimeSeconds()}.ini")); iniFileInfo.Delete(); } } @@ -601,28 +611,18 @@ internal class InterfaceManager : IDisposable, IServiceType Service.Provide(new(this)); } - /* - * NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg. - * Seems to work fine regardless, I guess, so whatever. - */ - private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags) + private void PresentCore(IntPtr swapChain) { if (this.scene == null) { this.InitScene(swapChain); } + else if (swapChain != this.scene.SwapChain.NativePointer) + { + return; + } - nint res; - if (this.address.IsReshade) - { - res = this.presentOriginal(swapChain, syncInterval, presentFlags); - this.RenderImGui(); - } - else - { - this.RenderImGui(); - res = this.presentOriginal(swapChain, syncInterval, presentFlags); - } + this.RenderImGui(); if (this.deferredDisposeTextures.Count > 0) { @@ -634,19 +634,40 @@ internal class InterfaceManager : IDisposable, IServiceType this.deferredDisposeTextures.Clear(); } - - return res; } - private void QueueHookResolution() + /* + * NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg. + * Seems to work fine regardless, I guess, so whatever. + */ + private IntPtr PresentDetour(IntPtr swapChain, uint syncInterval, uint presentFlags) { - if (this.GameWindowHandle != 0 && this.address.IsResolved) + this.PresentCore(swapChain); + return this.presentOriginal!(swapChain, syncInterval, presentFlags); + } + + private unsafe void QueueHookResolution() + { + if (this.GameWindowHandle != 0) { return; } this.framework.RunOnFrameworkThread(() => { + void* dxgiSwapChain; + try + { + var kernelDev = Util.NotNull(FFXIVClientStructs.FFXIV.Client.Graphics.Kernel.Device.Instance()); + var swapChain = Util.NotNull(kernelDev->SwapChain); + dxgiSwapChain = Util.NotNull(swapChain->DXGISwapChain); + } + catch (ArgumentNullException) + { + // Try again later + return; + } + if (this.GameWindowHandle == 0) { while ((this.GameWindowHandle = NativeFunctions.FindWindowEx(IntPtr.Zero, this.GameWindowHandle, "FFXIVGAME", IntPtr.Zero)) != IntPtr.Zero) @@ -677,52 +698,36 @@ internal class InterfaceManager : IDisposable, IServiceType Log.Error(ex, "Could not enable immersive mode"); } - if (!this.address.IsResolved) + this.swapChainHook = new(dxgiSwapChain); + + if (EntryPoint.TryRegisterReshadePresentCallback( + Marshal.GetFunctionPointerForDelegate(this.presentCoreDelegate = this.PresentCore))) { - try - { - this.address.Setup(); - } - catch (Exception ex) - { - Log.Error(ex, "Could not resolve addresses and set up hooks; trying again later"); - return; - } - - Log.Information("Resolver setup complete"); - - Log.Information("===== S W A P C H A I N ====="); - Log.Information($"Is ReShade: {this.address.IsReshade}"); - Log.Information($"Present address 0x{this.address.Present.ToInt64():X}"); - Log.Information($"ResizeBuffers address 0x{this.address.ResizeBuffers.ToInt64():X}"); - - this.presentOriginal = - Marshal.GetDelegateForFunctionPointer(this.address.Present); - this.resizeBuffersOriginal = - Marshal.GetDelegateForFunctionPointer(this.address.ResizeBuffers); - - this.swapChainHook = new ObjectVTableHook( - this.address.DxgiSwapChain, - SwapChainVtableResolver.NumDxgiSwapChainMethods); - this.swapChainHook.SetVtableEntry( - (int)IDXGISwapChainVtbl.Present, - this.PresentDetour); - this.swapChainHook.SetVtableEntry( - (int)IDXGISwapChainVtbl.ResizeBuffers, - this.ResizeBuffersDetour); - this.swapChainHook.Enable(); - Log.Information("Present and ResizeBuffers hooked"); - - var wndProcAddress = this.sigScanner.ScanText("E8 ?? ?? ?? ?? 80 7C 24 ?? ?? 74 ?? B8"); - Log.Information($"WndProc address 0x{wndProcAddress.ToInt64():X}"); - this.processMessageHook = - Hook.FromAddress(wndProcAddress, this.ProcessMessageDetour); - - this.setCursorHook.Enable(); - this.dispatchMessageWHook.Enable(); - this.processMessageHook.Enable(); - Log.Information("Hooks enabled"); + Log.Information("Using ReShade addon interface to provide implementation for Present."); } + else + { + Log.Information("Using IDXGISwapChain VTable forging to provide implementation for Present."); + this.swapChainHook.SetVtableEntry( + IDXGISwapChainVtbl.Present, + this.PresentDetour, + out this.presentOriginal); + } + + // Use ResizeBuffers, since we're hooking this just to be informed that it happened, + // and order does not matter whether we get called before or after ReShade. + this.swapChainHook.SetVtableEntry( + IDXGISwapChainVtbl.ResizeBuffers, + this.ResizeBuffersDetour, + out this.resizeBuffersOriginal); + + this.swapChainHook.Enable(); + Log.Information("Present and ResizeBuffers hooked"); + + this.setCursorHook.Enable(); + this.dispatchMessageWHook.Enable(); + this.processMessageHook.Enable(); + Log.Information("Hooks enabled"); }).ContinueWith(_ => this.QueueHookResolution()); } @@ -735,14 +740,14 @@ internal class InterfaceManager : IDisposable, IServiceType // Check if we can still enable viewports without any issues. this.CheckViewportState(); - this.scene.Render(); + this.scene!.Render(); } private void CheckViewportState() { var configuration = Service.Get(); - if (configuration.IsDisableViewport || this.scene.SwapChain.IsFullScreen || ImGui.GetPlatformIO().Monitors.Size == 1) + if (configuration.IsDisableViewport || this.scene!.SwapChain.IsFullScreen || ImGui.GetPlatformIO().Monitors.Size == 1) { ImGui.GetIO().ConfigFlags &= ~ImGuiConfigFlags.ViewportsEnable; return; @@ -811,7 +816,7 @@ internal class InterfaceManager : IDisposable, IServiceType this.UseAxis ? TargetFontModification.AxisMode.Overwrite : TargetFontModification.AxisMode.GameGlyphsOnly, this.UseAxis ? DefaultFontSizePx : DefaultFontSizePx + 1, io.FontGlobalScale); - Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis.Style.BaseSizePt, fontInfo.SourceAxis.Style.BaseSizePx); + Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis?.Style.BaseSizePt, fontInfo.SourceAxis?.Style.BaseSizePx); fontConfig.SizePixels = fontInfo.TargetSizePx * io.FontGlobalScale; if (this.UseAxis) { @@ -882,13 +887,15 @@ internal class InterfaceManager : IDisposable, IServiceType foreach (var (fontSize, requests) in extraFontRequests) { - List> codepointRanges = new(); - codepointRanges.Add(Tuple.Create(Fallback1Codepoint, Fallback1Codepoint)); - codepointRanges.Add(Tuple.Create(Fallback2Codepoint, Fallback2Codepoint)); - - // ImGui default ellipsis characters - codepointRanges.Add(Tuple.Create(0x2026, 0x2026)); - codepointRanges.Add(Tuple.Create(0x0085, 0x0085)); + List> codepointRanges = new() + { + new(Fallback1Codepoint, Fallback1Codepoint), + new(Fallback2Codepoint, Fallback2Codepoint), + + // ImGui default ellipsis characters + new(0x2026, 0x2026), + new(0x0085, 0x0085), + }; foreach (var request in requests) { @@ -922,7 +929,7 @@ internal class InterfaceManager : IDisposable, IServiceType if (this.UseAxis) { fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject(); - fontConfig.SizePixels = fontInfo.SourceAxis.Style.BaseSizePx; + fontConfig.SizePixels = fontInfo.SourceAxis!.Style.BaseSizePx; fontConfig.PixelSnapH = false; var sizedFont = ioFonts.AddFontDefault(fontConfig); @@ -952,7 +959,7 @@ internal class InterfaceManager : IDisposable, IServiceType this.BuildFonts?.InvokeSafely(); Log.Verbose("[FONT] OnBuildFonts OK!"); - for (int i = customFontFirstConfigIndex, i_ = ioFonts.ConfigData.Size; i < i_; i++) + for (int i = customFontFirstConfigIndex, iTo = ioFonts.ConfigData.Size; i < iTo; i++) { var config = ioFonts.ConfigData[i]; if (gameFontManager.OwnsFont(config.DstFont)) @@ -989,7 +996,7 @@ internal class InterfaceManager : IDisposable, IServiceType config.SizePixels = config.SizePixels * io.FontGlobalScale; } - for (int i = 0, i_ = ioFonts.ConfigData.Size; i < i_; i++) + for (int i = 0, iTo = ioFonts.ConfigData.Size; i < iTo; i++) { var config = ioFonts.ConfigData[i]; config.RasterizerGamma *= fontGamma; @@ -1035,7 +1042,7 @@ internal class InterfaceManager : IDisposable, IServiceType } else if (mod.Axis == TargetFontModification.AxisMode.GameGlyphsOnly) { - Log.Verbose("[FONT] {0}: Overwrite game specific glyphs from AXIS of size {1}px", mod.Name, mod.SourceAxis.ImFont.FontSize, font.FontSize); + Log.Verbose("[FONT] {0}: Overwrite game specific glyphs from AXIS of size {1}px (was {2}px)", mod.Name, mod.SourceAxis.ImFont.FontSize, font.FontSize); if (!this.UseAxis && font.NativePtr == DefaultFont.NativePtr) mod.SourceAxis.ImFont.FontSize -= 1; ImGuiHelpers.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, true, false, 0xE020, 0xE0DB); @@ -1050,7 +1057,7 @@ internal class InterfaceManager : IDisposable, IServiceType // Fill missing glyphs in MonoFont from DefaultFont ImGuiHelpers.CopyGlyphsAcrossFonts(DefaultFont, MonoFont, true, false); - for (int i = 0, i_ = ioFonts.Fonts.Size; i < i_; i++) + for (int i = 0, iTo = ioFonts.Fonts.Size; i < iTo; i++) { var font = ioFonts.Fonts[i]; if (font.Glyphs.Size == 0) @@ -1108,7 +1115,7 @@ internal class InterfaceManager : IDisposable, IServiceType private unsafe IntPtr ProcessMessageDetour(IntPtr hWnd, uint msg, ulong wParam, ulong lParam, IntPtr handeled) { var ime = Service.GetNullable(); - var res = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam); + _ = ime?.ProcessWndProcW(hWnd, (User32.WindowMessage)msg, (void*)wParam, (void*)lParam); return this.processMessageHook.Original(hWnd, msg, wParam, lParam, handeled); } @@ -1134,7 +1141,7 @@ internal class InterfaceManager : IDisposable, IServiceType this.scene?.OnPreResize(); - var ret = this.resizeBuffersOriginal(swapChain, bufferCount, width, height, newFormat, swapChainFlags); + var ret = this.resizeBuffersOriginal!(swapChain, bufferCount, width, height, newFormat, swapChainFlags); if (ret.ToInt64() == 0x887A0001) { Log.Error("invalid call to resizeBuffers"); @@ -1147,7 +1154,7 @@ internal class InterfaceManager : IDisposable, IServiceType private IntPtr SetCursorDetour(IntPtr hCursor) { - if (this.lastWantCapture == true && (!this.scene?.IsImGuiCursor(hCursor) ?? false) && this.OverrideGameCursor) + if (this.lastWantCapture && (!this.scene?.IsImGuiCursor(hCursor) ?? false) && this.OverrideGameCursor) return IntPtr.Zero; return this.setCursorHook.IsDisposed ? User32.SetCursor(new User32.SafeCursorHandle(hCursor, false)).DangerousGetHandle() : this.setCursorHook.Original(hCursor); diff --git a/Dalamud/NativeFunctions.cs b/Dalamud/NativeFunctions.cs index b77f71d08..92dfe5dd7 100644 --- a/Dalamud/NativeFunctions.cs +++ b/Dalamud/NativeFunctions.cs @@ -137,6 +137,7 @@ internal static partial class NativeFunctions /// /// MB_* from winuser. /// + [Flags] public enum MessageBoxType : uint { /// diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index cb60e60b8..b3e0e5d7f 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -555,14 +555,7 @@ public static class Util /// The value, ensured to be not null. public static unsafe T* NotNull(T* value, string what) where T : unmanaged - { - if (value == null) - { - throw new NullReferenceException($"{what} is null."); - } - - return value; - } + => value == null ? throw new NullReferenceException($"{what} is null.") : value; /// /// Ensures that a pointer is not null, or throw a @@ -571,14 +564,25 @@ public static class Util /// Help text for exception. /// The value, ensured to be not null. public static unsafe void* NotNull(void* value, string what) - { - if (value == null) - { - throw new NullReferenceException($"{what} is null."); - } + => value == null ? throw new NullReferenceException($"{what} is null.") : value; - return value; - } + /// + /// Ensures that a pointer is not null, or throw a + /// + /// Pointer value. + /// Backing data type of the pointer. + /// The value, ensured to be not null. + public static unsafe T* NotNull(T* value) + where T : unmanaged + => value == null ? throw new NullReferenceException() : value; + + /// + /// Ensures that a pointer is not null, or throw a + /// + /// Pointer value. + /// The value, ensured to be not null. + public static unsafe void* NotNull(void* value) + => value == null ? throw new NullReferenceException() : value; /// /// Open a link in the default browser. diff --git a/lib/reshade/include/reshade.hpp b/lib/reshade/include/reshade.hpp new file mode 100644 index 000000000..0b1b85c9c --- /dev/null +++ b/lib/reshade/include/reshade.hpp @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include "reshade_events.hpp" +#include "reshade_overlay.hpp" +#include +#include + +// Current version of the ReShade API +#define RESHADE_API_VERSION 8 + +// Optionally import ReShade API functions when 'RESHADE_API_LIBRARY' is defined instead of using header-only mode +#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT) + +#ifdef RESHADE_API_LIBRARY_EXPORT + #define RESHADE_API_LIBRARY_DECLSPEC extern "C" __declspec(dllexport) +#else + #define RESHADE_API_LIBRARY_DECLSPEC extern "C" __declspec(dllimport) +#endif + +RESHADE_API_LIBRARY_DECLSPEC void ReShadeLogMessage(HMODULE module, int level, const char *message); + +RESHADE_API_LIBRARY_DECLSPEC void ReShadeGetBasePath(char *path, size_t *path_size); + +RESHADE_API_LIBRARY_DECLSPEC bool ReShadeGetConfigValue(HMODULE module, reshade::api::effect_runtime *runtime, const char *section, const char *key, char *value, size_t *value_size); +RESHADE_API_LIBRARY_DECLSPEC void ReShadeSetConfigValue(HMODULE module, reshade::api::effect_runtime *runtime, const char *section, const char *key, const char *value); + +RESHADE_API_LIBRARY_DECLSPEC bool ReShadeRegisterAddon(HMODULE module, uint32_t api_version); +RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterAddon(HMODULE module); + +RESHADE_API_LIBRARY_DECLSPEC void ReShadeRegisterEvent(reshade::addon_event ev, void *callback); +RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterEvent(reshade::addon_event ev, void *callback); + +RESHADE_API_LIBRARY_DECLSPEC void ReShadeRegisterOverlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime)); +RESHADE_API_LIBRARY_DECLSPEC void ReShadeUnregisterOverlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime)); + +#else + +// Use the kernel32 variant of module enumeration functions so it can be safely called from 'DllMain' +extern "C" BOOL WINAPI K32EnumProcessModules(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded); + +namespace reshade { namespace internal +{ + /// + /// Gets the handle to the ReShade module. + /// + inline HMODULE get_reshade_module_handle(HMODULE reshade_module = nullptr) + { + static HMODULE handle = reshade_module; + if (handle == nullptr) + { + HMODULE modules[1024]; DWORD num = 0; + if (K32EnumProcessModules(GetCurrentProcess(), modules, sizeof(modules), &num)) + { + if (num > sizeof(modules)) + num = sizeof(modules); + + for (DWORD i = 0; i < num / sizeof(HMODULE); ++i) + { + if (GetProcAddress(modules[i], "ReShadeRegisterAddon") && + GetProcAddress(modules[i], "ReShadeUnregisterAddon")) + { + handle = modules[i]; + break; + } + } + } + } + return handle; + } + + /// + /// Gets the handle to the current add-on module. + /// + inline HMODULE get_current_module_handle(HMODULE addon_module = nullptr) + { + static HMODULE handle = addon_module; + return handle; + } +} } + +#endif + +namespace reshade +{ + /// + /// Available log severity levels. + /// + enum class log_level + { + error = 1, + warning = 2, + info = 3, + debug = 4 + }; + + /// + /// Writes a message to ReShade's log. + /// + /// Severity level. + /// A null-terminated message string. + inline void log_message(log_level level, const char *message) + { +#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT) + ReShadeLogMessage(nullptr, static_cast(level), message); +#else + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeLogMessage")); + func(internal::get_current_module_handle(), static_cast(level), message); +#endif + } + + /// + /// Gets the file path ReShade uses to resolve relative paths. + /// + /// Pointer to a string buffer that is filled with the file path to the preset, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + inline void get_reshade_base_path(char *path, size_t *path_size) + { +#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT) + ReShadeGetBasePath(path, path_size); +#else + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeGetBasePath")); + func(path, path_size); +#endif + } + + /// + /// Gets a value from one of ReShade's config files. + /// + /// Optional effect runtime to use the config file from, or to use the global config file. + /// Name of the config section. + /// Name of the config value. + /// Pointer to a string buffer that is filled with the config value, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + /// if the specified config value exists, otherwise. + inline bool get_config_value(api::effect_runtime *runtime, const char *section, const char *key, char *value, size_t *value_size) + { +#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT) + return ReShadeGetConfigValue(nullptr, runtime, section, key, value, value_size); +#else + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeGetConfigValue")); + return func(internal::get_current_module_handle(), runtime, section, key, value, value_size); +#endif + } +#if _HAS_CXX17 + template + inline bool get_config_value(api::effect_runtime *runtime, const char *section, const char *key, T &value) + { + char value_string[32]; size_t value_length = sizeof(value_string) - 1; + if (!get_config_value(runtime, section, key, value_string, &value_length)) + return false; + return std::from_chars(value_string, value_string + value_length, value).ec == std::errc {}; + } + template <> + inline bool get_config_value(api::effect_runtime *runtime, const char *section, const char *key, bool &value) + { + int value_int = 0; + if (!get_config_value(runtime, section, key, value_int)) + return false; + value = (value_int != 0); + return true; + } +#endif + + /// + /// Sets and saves a value in one of ReShade's config files. + /// + /// Optional effect runtime to use the config file from, or to use the global config file. + /// Name of the config section. + /// Name of the config value. + /// Config value to set. + inline void set_config_value(api::effect_runtime *runtime, const char *section, const char *key, const char *value) + { +#if defined(RESHADE_API_LIBRARY) || defined(RESHADE_API_LIBRARY_EXPORT) + ReShadeSetConfigValue(nullptr, runtime, section, key, value); +#else + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeSetConfigValue")); + func(internal::get_current_module_handle(), runtime, section, key, value); +#endif + } +#if _HAS_CXX17 + template + inline void set_config_value(api::effect_runtime *runtime, const char *section, const char *key, const T &value) + { + char value_string[32] = ""; + std::to_chars(value_string, value_string + sizeof(value_string) - 1, value); + set_config_value(runtime, section, key, static_cast(value_string)); + } + template <> + inline void set_config_value(api::effect_runtime *runtime, const char *section, const char *key, const bool &value) + { + set_config_value(runtime, section, key, value ? 1 : 0); + } +#endif + + /// + /// Registers this module as an add-on with ReShade. + /// Call this in 'AddonInit' or 'DllMain' during process attach, before any of the other API functions! + /// + /// Handle of the current module. + /// Handle of the ReShade module in the process, or to find it automatically. + inline bool register_addon(HMODULE addon_module, [[maybe_unused]] HMODULE reshade_module = nullptr) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON) + return ReShadeRegisterAddon(addon_module, RESHADE_API_VERSION); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + addon_module = internal::get_current_module_handle(addon_module); + reshade_module = internal::get_reshade_module_handle(reshade_module); + + if (reshade_module == nullptr) + return false; + + const auto func = reinterpret_cast( + GetProcAddress(reshade_module, "ReShadeRegisterAddon")); + // Check that the ReShade module supports the used API + if (func == nullptr || !func(addon_module, RESHADE_API_VERSION)) + return false; + +#if defined(IMGUI_VERSION_NUM) + const auto imgui_func = reinterpret_cast( + GetProcAddress(reshade_module, "ReShadeGetImGuiFunctionTable")); + // Check that the ReShade module was built with Dear ImGui support and supports the used version + if (imgui_func == nullptr || !(imgui_function_table_instance() = imgui_func(IMGUI_VERSION_NUM))) + return false; +#endif + + return true; +#else + UNREFERENCED_PARAMETER(addon_module); + UNREFERENCED_PARAMETER(reshade_module); + return false; +#endif + } + /// + /// Unregisters this module. + /// Call this in 'AddonUninit' or 'DllMain' during process detach, after any of the other API functions. + /// + /// Handle of the current module. + /// Handle of the ReShade module in the process, or to find it automatically. + inline void unregister_addon(HMODULE addon_module, [[maybe_unused]] HMODULE reshade_module = nullptr) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON) + ReShadeUnregisterAddon(addon_module); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + addon_module = internal::get_current_module_handle(addon_module); + reshade_module = internal::get_reshade_module_handle(reshade_module); + + if (reshade_module == nullptr) + return; + + const auto func = reinterpret_cast( + GetProcAddress(reshade_module, "ReShadeUnregisterAddon")); + if (func != nullptr) + func(addon_module); +#else + UNREFERENCED_PARAMETER(addon_module); + UNREFERENCED_PARAMETER(reshade_module); +#endif + } + + /// + /// Registers a callback for the specified event (via template) with ReShade. + /// The callback function is then called whenever the application performs a task associated with this event (see also the enumeration). + /// + /// Pointer to the callback function. + template + inline void register_event(typename reshade::addon_event_traits::decl callback) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON) + ReShadeRegisterEvent(ev, static_cast(callback)); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterEvent")); + if (func != nullptr) + func(ev, static_cast(callback)); +#else + UNREFERENCED_PARAMETER(callback); +#endif + } + /// + /// Unregisters a callback for the specified event (via template) that was previously registered via . + /// + /// Pointer to the callback function. + template + inline void unregister_event(typename reshade::addon_event_traits::decl callback) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON) + ReShadeUnregisterEvent(ev, static_cast(callback)); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterEvent")); + if (func != nullptr) + func(ev, static_cast(callback)); +#else + UNREFERENCED_PARAMETER(callback); +#endif + } + + /// + /// Registers an overlay with ReShade. + /// The callback function is then called when the overlay is visible and allows adding Dear ImGui widgets for user interaction. + /// + /// Null-terminated title string, or to register a settings overlay for this add-on. + /// Pointer to the callback function. + inline void register_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime)) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON && RESHADE_GUI) + ReShadeRegisterOverlay(title, callback); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeRegisterOverlay")); + if (func != nullptr) + func(title, callback); +#else + UNREFERENCED_PARAMETER(title); + UNREFERENCED_PARAMETER(callback); +#endif + } + /// + /// Unregisters an overlay that was previously registered via . + /// + /// Null-terminated title string. + /// Pointer to the callback function. + inline void unregister_overlay(const char *title, void(*callback)(reshade::api::effect_runtime *runtime)) + { +#if defined(RESHADE_API_LIBRARY) || (defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON && RESHADE_GUI) + ReShadeUnregisterOverlay(title, callback); +#elif !defined(RESHADE_API_LIBRARY_EXPORT) + static const auto func = reinterpret_cast( + GetProcAddress(internal::get_reshade_module_handle(), "ReShadeUnregisterOverlay")); + if (func != nullptr) + func(title, callback); +#else + UNREFERENCED_PARAMETER(title); + UNREFERENCED_PARAMETER(callback); +#endif + } +} diff --git a/lib/reshade/include/reshade_api.hpp b/lib/reshade/include/reshade_api.hpp new file mode 100644 index 000000000..4691bd4d3 --- /dev/null +++ b/lib/reshade/include/reshade_api.hpp @@ -0,0 +1,726 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include "reshade_api_device.hpp" + +namespace reshade { namespace api +{ + /// + /// An opaque handle to a technique in an effect. + /// + /// + /// This handle is only valid until effects are next reloaded again (). + /// + RESHADE_DEFINE_HANDLE(effect_technique); + /// + /// An opaque handle to a texture variable in an effect. + /// + /// + /// This handle is only valid until effects are next reloaded again (). + /// + RESHADE_DEFINE_HANDLE(effect_texture_variable); + /// + /// An opaque handle to a uniform variable in an effect. + /// + /// + /// This handle is only valid until effects are next reloaded again (). + /// + RESHADE_DEFINE_HANDLE(effect_uniform_variable); + + /// + /// A ReShade effect runtime, used to control effects. + /// A separate runtime is instantiated for every swap chain. + /// + struct __declspec(novtable) effect_runtime : public swapchain + { + /// + /// Gets the main graphics command queue associated with this effect runtime. + /// This may potentially be different from the presentation queue and should be used to execute graphics commands on. + /// + virtual command_queue *get_command_queue() = 0; + + /// + /// Applies post-processing effects to the specified render targets and prevents the usual rendering of effects before swap chain presentation of the current frame. + /// This can be used to force ReShade to render effects at a certain point during the frame to e.g. avoid effects being applied to user interface elements of the application. + /// + /// + /// The resource the render target views point to has to be in the state. + /// This call may modify current state on the command list (pipeline, render targets, descriptor tables, ...), so it may be necessary for an add-on to backup and restore state around it if the application does not bind all state again afterwards already. + /// Calling this with set to zero will cause nothing to be rendered, but uniform variables to still be updated. + /// + /// Command list to add effect rendering commands to. + /// Render target view to use for passes that write to the back buffer with SRGBWriteEnabled state set to . + /// Render target view to use for passes that write to the back buffer with SRGBWriteEnabled state set to , or zero in which case the view from is used. + virtual void render_effects(command_list *cmd_list, resource_view rtv, resource_view rtv_srgb = { 0 }) = 0; + + /// + /// Captures a screenshot of the current back buffer resource and returns its image data in 32 bits-per-pixel RGBA format. + /// + /// Pointer to an array of width * height * 4 bytes the image data is written to. + virtual bool capture_screenshot(uint8_t *pixels) = 0; + + /// + /// Gets the current buffer dimensions of the swap chain. + /// + virtual void get_screenshot_width_and_height(uint32_t *out_width, uint32_t *out_height) const = 0; + + /// + /// Gets the current status of the specified key. + /// + /// The virtual key code to check. + /// if the key is currently pressed down, otherwise. + virtual bool is_key_down(uint32_t keycode) const = 0; + /// + /// Gets whether the specified key was pressed this frame. + /// + /// The virtual key code to check. + /// if the key was pressed this frame, otherwise. + virtual bool is_key_pressed(uint32_t keycode) const = 0; + /// + /// Gets whether the specified key was released this frame. + /// + /// The virtual key code to check. + /// if the key was released this frame, otherwise. + virtual bool is_key_released(uint32_t keycode) const = 0; + /// + /// Gets the current status of the specified mouse button. + /// + /// The mouse button index to check (0 = left, 1 = middle, 2 = right). + /// if the mouse button is currently pressed down, otherwise. + virtual bool is_mouse_button_down(uint32_t button) const = 0; + /// + /// Gets whether the specified mouse button was pressed this frame. + /// + /// The mouse button index to check (0 = left, 1 = middle, 2 = right). + /// if the mouse button was pressed this frame, otherwise. + virtual bool is_mouse_button_pressed(uint32_t button) const = 0; + /// + /// Gets whether the specified mouse button was released this frame. + /// + /// The mouse button index to check (0 = left, 1 = middle, 2 = right). + /// if the mouse button was released this frame, otherwise. + virtual bool is_mouse_button_released(uint32_t button) const = 0; + + /// + /// Gets the current absolute position of the mouse cursor in screen coordinates. + /// + /// Pointer to a variable that is set to the X coordinate of the current cursor position. + /// Pointer to a variable that is set to the Y coordinate of the current cursor position. + /// Optional pointer to a variable that is set to the mouse wheel delta since the last frame. + virtual void get_mouse_cursor_position(uint32_t *out_x, uint32_t *out_y, int16_t *out_wheel_delta = nullptr) const = 0; + + /// + /// Enumerates all uniform variables of loaded effects and calls the specified function with a handle for each one. + /// + /// File name of the effect file to enumerate uniform variables from, or to enumerate those of all loaded effects. + /// Function to call for every uniform variable. + /// Optional pointer passed to the callback function. + virtual void enumerate_uniform_variables(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_uniform_variable variable, void *user_data), void *user_data) = 0; + /// + /// Enumerates all uniform variables of loaded effects and calls the specified callback function with a handle for each one. + /// + /// File name of the effect file to enumerate uniform variables from, or to enumerate those of all loaded effects. + /// Function to call for every uniform variable. + template + inline void enumerate_uniform_variables(const char *effect_name, F lambda) + { + enumerate_uniform_variables(effect_name, [](effect_runtime *runtime, effect_uniform_variable variable, void *user_data) { static_cast(user_data)->operator()(runtime, variable); }, &lambda); + } + + /// + /// Finds a specific uniform variable in the loaded effects and returns a handle to it. + /// + /// File name of the effect file the variable is declared in, or to search in all loaded effects. + /// Name of the uniform variable declaration to find. + /// Opaque handle to the uniform variable, or zero in case it was not found. + virtual effect_uniform_variable find_uniform_variable(const char *effect_name, const char *variable_name) const = 0; + + /// + /// Gets information about the data type of a uniform . + /// + /// Opaque handle to the uniform variable. + /// Optional pointer to a variable that is set to the base type of the uniform variable (, , or ). + /// Optional pointer to a variable that is set to the number of vector rows of the uniform variable type. + /// Optional pointer to a variable that is set to the number of matrix column of the uniform variable type. + /// Optional pointer to a variable that is set to the number of array elements of the uniform variable type. + virtual void get_uniform_variable_type(effect_uniform_variable variable, format *out_base_type, uint32_t *out_rows = nullptr, uint32_t *out_columns = nullptr, uint32_t *out_array_length = nullptr) const = 0; + + /// + /// Gets the name of a uniform . + /// + /// Opaque handle to the uniform variable. + /// Pointer to a string buffer that is filled with the name of the uniform variable, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_uniform_variable_name(effect_uniform_variable variable, char *name, size_t *name_size) const = 0; + template + inline void get_uniform_variable_name(effect_uniform_variable variable, char(&name)[SIZE]) const + { + size_t name_size = SIZE; + get_uniform_variable_name(variable, name, &name_size); + } + + /// + /// Gets the value from an annotation attached to the specified uniform as boolean values. + /// + /// Opaque handle to the uniform variable. + /// Name of the annotation. + /// Pointer to an array of booleans that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_bool_from_uniform_variable(effect_uniform_variable variable, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified uniform as floating-point values. + /// + /// Opaque handle to the uniform variable. + /// Name of the annotation. + /// Pointer to an array of floating-points that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_float_from_uniform_variable(effect_uniform_variable variable, const char *name, float *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified uniform as signed integer values. + /// + /// Opaque handle to the uniform variable. + /// Name of the annotation. + /// Pointer to an array of signed integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_int_from_uniform_variable(effect_uniform_variable variable, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified uniform as unsigned integer values. + /// + /// Opaque handle to the uniform variable. + /// Name of the annotation. + /// Pointer to an array of unsigned integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_uint_from_uniform_variable(effect_uniform_variable variable, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from a string annotation attached to the specified uniform . + /// + /// Opaque handle to the uniform variable. + /// Name of the annotation. + /// Pointer to a string buffer that is filled with the value of the annotation, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual bool get_annotation_string_from_uniform_variable(effect_uniform_variable variable, const char *name, char *value, size_t *value_size) const = 0; + template + inline bool get_annotation_string_from_uniform_variable(effect_uniform_variable variable, const char *name, char(&value)[SIZE]) const + { + size_t value_size = SIZE; + return get_annotation_string_from_uniform_variable(variable, name, value, &value_size); + } + + /// + /// Gets the value of the specified uniform as boolean values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of booleans that is filled with the values of this uniform variable. + /// Number of values to read. + /// Array offset to start reading values from when this uniform variable is an array variable. + virtual void get_uniform_value_bool(effect_uniform_variable variable, bool *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value of the specified uniform as floating-point values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of floating-points that is filled with the values of this uniform variable. + /// Number of values to read. + /// Array offset to start reading values from when this uniform variable is an array variable. + virtual void get_uniform_value_float(effect_uniform_variable variable, float *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value of the specified uniform as signed integer values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of signed integers that is filled with the values of this uniform variable. + /// Number of values to read. + /// Array offset to start reading values from when this uniform variable is an array variable. + virtual void get_uniform_value_int(effect_uniform_variable variable, int32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value of the specified uniform as unsigned integer values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of unsigned integers that is filled with the values of this uniform variable. + /// Number of values to read. + /// Array offset to start reading values from when this uniform variable is an array variable. + virtual void get_uniform_value_uint(effect_uniform_variable variable, uint32_t *values, size_t count, size_t array_index = 0) const = 0; + + /// + /// Sets the value of the specified uniform as boolean values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of booleans that are used to update this uniform variable. + /// Number of values to write. + /// Array offset to start writing values to when this uniform variable is an array variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + virtual void set_uniform_value_bool(effect_uniform_variable variable, const bool *values, size_t count, size_t array_index = 0) = 0; + /// + /// Sets the value of the specified uniform as a vector of boolean values. + /// + /// Opaque handle to the uniform variable. + /// Value of the first component in the vector that is used to update this uniform variable. + /// Optional value of the second component in the vector that is used to update this uniform variable. + /// Optional value of the third component in the vector that is used to update this uniform variable. + /// Optional value of the fourth component in the vector that is used to update this uniform variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + inline void set_uniform_value_bool(effect_uniform_variable variable, bool x, bool y = bool(0), bool z = bool(0), bool w = bool(0)) + { + const bool values[4] = { x, y, z, w }; + set_uniform_value_bool(variable, values, 4); + } + /// + /// Sets the value of the specified uniform as floating-point values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of floating-points that are used to update this uniform variable. + /// Number of values to write. + /// Array offset to start writing values to when this uniform variable is an array variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + virtual void set_uniform_value_float(effect_uniform_variable variable, const float *values, size_t count, size_t array_index = 0) = 0; + /// + /// Sets the value of the specified uniform as a vector of floating-point values. + /// + /// Opaque handle to the uniform variable. + /// Value of the first component in the vector that is used to update this uniform variable. + /// Optional value of the second component in the vector that is used to update this uniform variable. + /// Optional value of the third component in the vector that is used to update this uniform variable. + /// Optional value of the fourth component in the vector that is used to update this uniform variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + inline void set_uniform_value_float(effect_uniform_variable variable, float x, float y = float(0), float z = float(0), float w = float(0)) + { + const float values[4] = { x, y, z, w }; + set_uniform_value_float(variable, values, 4); + } + /// + /// Sets the value of the specified uniform as signed integer values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of signed integers that are used to update this uniform variable. + /// Number of values to write. + /// Array offset to start writing values to when this uniform variable is an array variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + virtual void set_uniform_value_int(effect_uniform_variable variable, const int32_t *values, size_t count, size_t array_index = 0) = 0; + /// + /// Sets the value of the specified uniform as a vector of signed integer values. + /// + /// Opaque handle to the uniform variable. + /// Value of the first component in the vector that is used to update this uniform variable. + /// Optional value of the second component in the vector that is used to update this uniform variable. + /// Optional value of the third component in the vector that is used to update this uniform variable. + /// Optional value of the fourth component in the vector that is used to update this uniform variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + inline void set_uniform_value_int(effect_uniform_variable variable, int32_t x, int32_t y = int32_t(0), int32_t z = int32_t(0), int32_t w = int32_t(0)) + { + const int32_t values[4] = { x, y, z, w }; + set_uniform_value_int(variable, values, 4); + } + /// + /// Sets the value of the specified uniform as unsigned integer values. + /// + /// Opaque handle to the uniform variable. + /// Pointer to an array of unsigned integers that are used to update this uniform variable. + /// Number of values to write. + /// Array offset to start writing values to when this uniform variable is an array variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + virtual void set_uniform_value_uint(effect_uniform_variable variable, const uint32_t *values, size_t count, size_t array_index = 0) = 0; + /// + /// Sets the value of the specified uniform as a vector of unsigned integer values. + /// + /// Opaque handle to the uniform variable. + /// Value of the first component in the vector that is used to update this uniform variable. + /// Optional value of the second component in the vector that is used to update this uniform variable. + /// Optional value of the third component in the vector that is used to update this uniform variable. + /// Optional value of the fourth component in the vector that is used to update this uniform variable. + /// Setting the uniform value won't result in a save of the current preset. To make sure the current preset with the changed value + /// is saved to disk, call + inline void set_uniform_value_uint(effect_uniform_variable variable, uint32_t x, uint32_t y = uint32_t(0), uint32_t z = uint32_t(0), uint32_t w = uint32_t(0)) + { + const uint32_t values[4] = { x, y, z, w }; + set_uniform_value_uint(variable, values, 4); + } + + /// + /// Enumerates all texture variables of loaded effects and calls the specified function with a handle for each one. + /// + /// File name of the effect file to enumerate texture variables from, or to enumerate those of all loaded effects. + /// Function to call for every texture variable. + /// Optional pointer passed to the callback function. + virtual void enumerate_texture_variables(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_texture_variable variable, void *user_data), void *user_data) = 0; + /// + /// Enumerates all texture variables of loaded effects and calls the specified callback function with a handle for each one. + /// + /// File name of the effect file to enumerate texture variables from, or to enumerate those of all loaded effects. + /// Function to call for every texture variable. + template + inline void enumerate_texture_variables(const char *effect_name, F lambda) + { + enumerate_texture_variables(effect_name, [](effect_runtime *runtime, effect_texture_variable variable, void *user_data) { static_cast(user_data)->operator()(runtime, variable); }, &lambda); + } + + /// + /// Finds a specific texture variable in the loaded effects and returns a handle to it. + /// + /// File name of the effect file the variable is declared in, or to search in all loaded effects. + /// Name of the texture variable declaration to find. + /// Opaque handle to the texture variable, or zero in case it was not found. + virtual effect_texture_variable find_texture_variable(const char *effect_name, const char *variable_name) const = 0; + + /// + /// Gets the name of a texture . + /// + /// Opaque handle to the texture variable. + /// Pointer to a string buffer that is filled with the name of the texture variable, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_texture_variable_name(effect_texture_variable variable, char *name, size_t *name_size) const = 0; + template + inline void get_texture_variable_name(effect_texture_variable variable, char(&name)[SIZE]) const + { + size_t name_size = SIZE; + get_texture_variable_name(variable, name, &name_size); + } + + /// + /// Gets the value from an annotation attached to the specified texture as boolean values. + /// + /// Opaque handle to the texture variable. + /// Name of the annotation. + /// Pointer to an array of booleans that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_bool_from_texture_variable(effect_texture_variable variable, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified texture as floating-point values. + /// + /// Opaque handle to the texture variable. + /// Name of the annotation. + /// Pointer to an array of floating-points that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_float_from_texture_variable(effect_texture_variable variable, const char *name, float *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified texture as signed integer values. + /// + /// Opaque handle to the texture variable. + /// Name of the annotation. + /// Pointer to an array of signed integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_int_from_texture_variable(effect_texture_variable variable, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified texture as unsigned integer values. + /// + /// Opaque handle to the texture variable. + /// Name of the annotation. + /// Pointer to an array of unsigned integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_uint_from_texture_variable(effect_texture_variable variable, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from a string annotation attached to the specified texture . + /// + /// Opaque handle to the texture variable. + /// Name of the annotation. + /// Pointer to a string buffer that is filled with the value of the annotation, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual bool get_annotation_string_from_texture_variable(effect_texture_variable variable, const char *name, char *value, size_t *value_size) const = 0; + template + inline bool get_annotation_string_from_texture_variable(effect_texture_variable variable, const char *name, char(&value)[SIZE]) const + { + size_t value_size = SIZE; + return get_annotation_string_from_texture_variable(variable, name, value, &value_size); + } + + /// + /// Uploads 32 bits-per-pixel RGBA image data to the specified texture . + /// + /// Opaque handle to the texture variable. + /// Width of the image data. + /// Height of the image data. + /// Pointer to an array of width * height * 4 bytes the image data is read from. + virtual void update_texture(effect_texture_variable variable, const uint32_t width, const uint32_t height, const uint8_t *pixels) = 0; + + /// + /// Gets the shader resource view that is bound to the specified texture . + /// + /// Opaque handle to the texture variable. + /// Pointer to a variable that is set to the shader resource view. + /// Pointer to a variable that is set to the sRGB shader resource view. + virtual void get_texture_binding(effect_texture_variable variable, resource_view *out_srv, resource_view *out_srv_srgb = nullptr) const = 0; + + /// + /// Binds a new shader resource view to all texture variables that use the specified . + /// + /// + /// The resource the shader resource views point to has to be in the state at the time is executed. + /// + /// ReShade FX semantic to filter textures to update by (texture name : SEMANTIC). + /// Shader resource view to use for samplers with SRGBTexture state set to . + /// Shader resource view to use for samplers with SRGBTexture state set to , or zero in which case the view from is used. + virtual void update_texture_bindings(const char *semantic, resource_view srv, resource_view srv_srgb = { 0 }) = 0; + + /// + /// Enumerates all techniques of loaded effects and calls the specified function with a handle for each one. + /// + /// File name of the effect file to enumerate techniques from, or to enumerate those of all loaded effects. + /// Function to call for every technique. + /// Optional pointer passed to the callback function. + virtual void enumerate_techniques(const char *effect_name, void(*callback)(effect_runtime *runtime, effect_technique technique, void *user_data), void *user_data) = 0; + /// + /// Enumerates all techniques of loaded effects and calls the specified callback function with a handle for each one. + /// + /// File name of the effect file to enumerate techniques from, or to enumerate those of all loaded effects. + /// Function to call for every technique. + template + inline void enumerate_techniques(const char *effect_name, F lambda) + { + enumerate_techniques(effect_name, [](effect_runtime *runtime, effect_technique technique, void *user_data) { static_cast(user_data)->operator()(runtime, technique); }, &lambda); + } + + /// + /// Finds a specific technique in the loaded effects and returns a handle to it. + /// + /// File name of the effect file the technique is declared in, or to search in all loaded effects. + /// Name of the technique to find. + /// Opaque handle to the technique, or zero in case it was not found. + virtual effect_technique find_technique(const char *effect_name, const char *technique_name) = 0; + + /// + /// Gets the name of a . + /// + /// Opaque handle to the technique. + /// Pointer to a string buffer that is filled with the name of the technique, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_technique_name(effect_technique technique, char *name, size_t *name_size) const = 0; + template + inline void get_technique_name(effect_technique technique, char(&name)[SIZE]) const + { + size_t name_size = SIZE; + get_technique_name(technique, name, &name_size); + } + + /// + /// Gets the value from an annotation attached to the specified as boolean values. + /// + /// Opaque handle to the technique. + /// Name of the annotation. + /// Pointer to an array of booleans that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_bool_from_technique(effect_technique technique, const char *name, bool *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified as floating-point values. + /// + /// Opaque handle to the technique. + /// Name of the annotation. + /// Pointer to an array of floating-points that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_float_from_technique(effect_technique technique, const char *name, float *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified as signed integer values. + /// + /// Opaque handle to the technique. + /// Name of the annotation. + /// Pointer to an array of signed integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_int_from_technique(effect_technique technique, const char *name, int32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from an annotation attached to the specified as unsigned integer values. + /// + /// Opaque handle to the technique. + /// Name of the annotation. + /// Pointer to an array of unsigned integers that is filled with the values of the annotation. + /// Number of values to read. + /// Array offset to start reading values from when the annotation is an array. + virtual bool get_annotation_uint_from_technique(effect_technique technique, const char *name, uint32_t *values, size_t count, size_t array_index = 0) const = 0; + /// + /// Gets the value from a string annotation attached to the specified . + /// + /// Opaque handle to the technique. + /// Name of the annotation. + /// Pointer to a string buffer that is filled with the value of the annotation, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual bool get_annotation_string_from_technique(effect_technique technique, const char *name, char *value, size_t *value_size) const = 0; + template + inline bool get_annotation_string_from_technique(effect_technique technique, const char *name, char(&value)[SIZE]) const + { + size_t value_size = SIZE; + return get_annotation_string_from_technique(technique, name, value, &value_size); + } + + /// + /// Gets the state of a . + /// + /// Opaque handle to the technique. + virtual bool get_technique_state(effect_technique technique) const = 0; + /// + /// Enables or disables the specified . + /// + /// Opaque handle to the technique. + /// Set to to enable the technique, or to disable it. + virtual void set_technique_state(effect_technique technique, bool enabled) = 0; + + /// + /// Gets the value of a preprocessor definition. + /// + /// Name of the definition. + /// Pointer to a string buffer that is filled with the value of the definition, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual bool get_preprocessor_definition(const char *name, char *value, size_t *value_size) const = 0; + template + inline bool get_preprocessor_definition(const char *name, char(&value)[SIZE]) const + { + size_t value_size = SIZE; + return get_preprocessor_definition(name, value, &value_size); + } + /// + /// Defines a preprocessor definition to the specified . + /// + /// Name of the definition. + /// Value of the definition. + virtual void set_preprocessor_definition(const char *name, const char *value) = 0; + + /// + /// Applies a to the specified render targets (regardless of the state of this technique). + /// + /// + /// The width and height of the specified render target should match those used to render all other effects! + /// The resource the render target views point to has to be in the state. + /// This call may modify current state on the command list (pipeline, render targets, descriptor tables, ...), so it may be necessary for an add-on to backup and restore state around it if the application does not bind all state again afterwards already. + /// + /// Opaque handle to the technique. + /// Command list to add effect rendering commands to. + /// Render target view to use for passes that write to the back buffer with SRGBWriteEnabled state set to . + /// Render target view to use for passes that write to the back buffer with SRGBWriteEnabled state set to , or zero in which case the view from is used. + virtual void render_technique(effect_technique technique, command_list *cmd_list, resource_view rtv, resource_view rtv_srgb = { 0 }) = 0; + + /// + /// Gets whether effects are enabled or disabled. + /// + virtual bool get_effects_state() const = 0; + /// + /// Enables or disables all effects. + /// + /// Set to to enable effects, or to disable them. + virtual void set_effects_state(bool enabled) = 0; + + /// + /// Gets the file path to the currently active preset. + /// + /// Pointer to a string buffer that is filled with the file path to the preset, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_current_preset_path(char *path, size_t *path_size) const = 0; + template + inline void get_current_preset_path(char(&path)[SIZE]) const + { + size_t path_size = SIZE; + get_current_preset_path(path, &path_size); + } + /// + /// Saves the currently active preset and then switches to the specified new preset. + /// + /// File path to the preset to switch to. + virtual void set_current_preset_path(const char *path) = 0; + + /// + /// Changes the rendering order of loaded techniques to that of the specified technique list. + /// + /// Number of handles in the technique list. + /// Array of techniques in the order they should be rendered in. + virtual void reorder_techniques(size_t count, const effect_technique *techniques) = 0; + + /// + /// Makes ReShade block any keyboard and mouse input from reaching the game for the duration of the next frame. + /// Call this every frame for as long as input should be blocked. This can be used to ensure input is only applied to overlays created in a callback. + /// + virtual void block_input_next_frame() = 0; + + /// + /// Gets the virtual key code of the last key that was pressed. + /// + virtual uint32_t last_key_pressed() const = 0; + /// + /// Gets the virtual key code of the last key that was released. + /// + virtual uint32_t last_key_released() const = 0; + + /// + /// Gets the effect file name of a uniform . + /// + /// Opaque handle to the uniform variable. + /// Pointer to a string buffer that is filled with the effect file name of the uniform variable, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_uniform_variable_effect_name(effect_uniform_variable variable, char *effect_name, size_t *effect_name_size) const = 0; + template + inline void get_uniform_variable_effect_name(effect_uniform_variable variable, char(&effect_name)[SIZE]) const + { + size_t effect_name_size = SIZE; + get_uniform_variable_effect_name(variable, effect_name, &effect_name_size); + } + + /// + /// Gets the effect file name of a texture . + /// + /// Opaque handle to the texture variable. + /// Pointer to a string buffer that is filled with the effect file name of the texture variable, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_texture_variable_effect_name(effect_texture_variable variable, char *effect_name, size_t *effect_name_size) const = 0; + template + inline void get_texture_variable_effect_name(effect_texture_variable variable, char(&effect_name)[SIZE]) const + { + size_t effect_name_size = SIZE; + get_texture_variable_effect_name(variable, effect_name, &effect_name_size); + } + + /// + /// Gets the effect file name of a . + /// + /// Opaque handle to the technique. + /// Pointer to a string buffer that is filled with the effect file name of the technique, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and is set to the actual length of the string, including the null-terminator. + virtual void get_technique_effect_name(effect_technique technique, char *effect_name, size_t *effect_name_size) const = 0; + template + inline void get_technique_effect_name(effect_technique technique, char(&effect_name)[SIZE]) const + { + size_t effect_name_size = SIZE; + get_technique_effect_name(technique, effect_name, &effect_name_size); + } + + /// + /// Saves the current preset with the current state of the loaded techniques and uniform variables. + /// + virtual void save_current_preset() const = 0; + + /// + /// Gets the value of a preprocessor definition for the specified effect. + /// + /// File name of the effect file the preprocessor definition is defined for. + /// Name of the definition. + /// Pointer to a string buffer that is filled with the value of the definition, or to query the necessary size. + /// Pointer to an integer that contains the size of the string buffer and upon completion is set to the actual length of the string, including the null-terminator. + virtual bool get_preprocessor_definition_for_effect(const char *effect_name, const char *name, char *value, size_t *value_size) const = 0; + template + inline bool get_preprocessor_definition_for_effect(const char *effect_name, const char *name, char(&value)[SIZE]) const + { + size_t value_size = SIZE; + return get_preprocessor_definition_for_effect(effect_name, name, value, &value_size); + } + /// + /// Defines a preprocessor definition for the specified effect to the specified . + /// + /// File name of the effect file the preprocessor definition should be defined for. + /// Name of the definition. + /// Value of the definition. + virtual void set_preprocessor_definition_for_effect(const char *effect_name, const char *name, const char *value) = 0; + }; +} } diff --git a/lib/reshade/include/reshade_api_device.hpp b/lib/reshade/include/reshade_api_device.hpp new file mode 100644 index 000000000..92f8c3b3e --- /dev/null +++ b/lib/reshade/include/reshade_api_device.hpp @@ -0,0 +1,1017 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include "reshade_api_pipeline.hpp" + +namespace reshade { namespace api +{ + /// + /// The underlying render API a device is using, as returned by . + /// + enum class device_api + { + /// Direct3D 9 + /// https://docs.microsoft.com/windows/win32/direct3d9 + d3d9 = 0x9000, + /// Direct3D 10 + /// https://docs.microsoft.com/windows/win32/direct3d10 + d3d10 = 0xa000, + /// Direct3D 11 + /// https://docs.microsoft.com/windows/win32/direct3d11 + d3d11 = 0xb000, + /// Direct3D 12 + /// https://docs.microsoft.com/windows/win32/direct3d12 + d3d12 = 0xc000, + /// OpenGL + /// https://www.khronos.org/opengl/ + opengl = 0x10000, + /// Vulkan + /// https://www.khronos.org/vulkan/ + vulkan = 0x20000 + }; + + /// + /// The available features a device may support. + /// + enum class device_caps + { + /// + /// Specifies whether compute shaders are supported. + /// If this feature is not present, the stage and must not be used. + /// + compute_shader = 1, + /// + /// Specifies whether geometry shaders are supported. + /// If this feature is not present, the stage must not be used. + /// + geometry_shader, + /// + /// Specifies whether hull and domain (tessellation) shaders are supported. + /// If this feature is not present, the and stages must not be used. + /// + hull_and_domain_shader, + /// + /// Specifies whether logic operations are available in the blend state. + /// If this feature is not present, the and fields are ignored. + /// + logic_op, + /// + /// Specifies whether blend operations which take two sources are supported. + /// If this feature is not present, , , and must not be used. + /// + dual_source_blend, + /// + /// Specifies whether blend state is controlled independently per render target. + /// If this feature is not present, the blend state settings for all render targets must be identical. + /// + independent_blend, + /// + /// Specifies whether point and wireframe fill modes are supported. + /// If this feature is not present, and must not be used. + /// + fill_mode_non_solid, + /// + /// Specifies whether conservative rasterization is supported. + /// If this feature is not present, the field must be 0. + /// + conservative_rasterization, + /// + /// Specifies whether binding individual render target and depth-stencil resource views is supported. + /// If this feature is not present, must not be used (only render passes). + /// + bind_render_targets_and_depth_stencil, + /// + /// Specifies whther more than one viewport is supported. + /// If this feature is not present, the "first" and "count" parameters to and must be 0 and 1. + /// + multi_viewport, + /// + /// Specifies whether partial push constant updates are supported. + /// If this feature is not present, the "first" parameter to must be 0 and "count" must cover the entire constant range. + /// + partial_push_constant_updates, + /// + /// Specifies whether partial push descriptor updates are supported. + /// If this feature is not present, the "first" parameter to must be 0 and "count" must cover the entire descriptor range. + /// + partial_push_descriptor_updates, + /// + /// Specifies whether instancing is supported. + /// If this feature is not present, the "instance_count" and "first_instance" parameters to and must be 1 and 0. + /// + draw_instanced, + /// + /// Specifies whether indirect draw or dispatch calls are supported. + /// If this feature is not present, must not be used. + /// + draw_or_dispatch_indirect, + /// + /// Specifies whether copying between buffers is supported. + /// If this feature is not present, must not be used. + /// + copy_buffer_region, + /// + /// Specifies whether copying between buffers and textures is supported. + /// If this feature is not present, and must not be used. + /// + copy_buffer_to_texture, + /// + /// Specifies whether blitting between resources is supported. + /// If this feature is not present, the "source_box" and "dest_box" parameters to must have the same dimensions. + /// + blit, + /// + /// Specifies whether resolving a region of a resource rather than its entirety is supported. + /// If this feature is not present, the "source_box", "dest_x", "dest_y" and "dest_z" parameters to must be and zero. + /// + resolve_region, + /// + /// Specifies whether copying query results to a buffer is supported. + /// If this feature is not present, must not be used. + /// + copy_query_heap_results, + /// + /// Specifies whether comparison sampling is supported. + /// If this feature is not present, the field is ignored and the compare filter types have no effect. + /// + sampler_compare, + /// + /// Specifies whether anisotropic filtering is supported. + /// If this feature is not present, must not be used. + /// + sampler_anisotropic, + /// + /// Specifies whether combined sampler and resource view descriptors are supported. + /// If this feature is not present, must not be used. + /// + sampler_with_resource_view, + /// + /// Specifies whether resource sharing is supported. + /// If this feature is not present, must not be used. + /// + shared_resource, + /// + /// Specifies whether resource sharing with NT handles is supported. + /// If this feature is not present, must not be used. + /// + shared_resource_nt_handle + }; + + /// + /// The base class for objects provided by the ReShade API. + /// This lets you store and retrieve custom data with objects, e.g. to be able to communicate persistent information between event callbacks. + /// + struct __declspec(novtable) api_object + { + /// + /// Gets the underlying native object for this API object. + /// + /// + /// For this will be be a pointer to a 'IDirect3DDevice9', 'ID3D10Device', 'ID3D11Device' or 'ID3D12Device' object or a 'HGLRC' or 'VkDevice' handle.
+ /// For this will be a pointer to a 'ID3D11DeviceContext' (when recording), 'ID3D11CommandList' (when executing) or 'ID3D12GraphicsCommandList' object or a 'VkCommandBuffer' handle.
+ /// For this will be a pointer to a 'ID3D11DeviceContext' or 'ID3D12CommandQueue' object or a 'VkQueue' handle.
+ /// For this will be a pointer to a 'IDirect3DSwapChain9' or 'IDXGISwapChain' object or a 'HDC' or 'VkSwapchainKHR' handle. + ///
+ virtual uint64_t get_native() const = 0; + + /// + /// Gets a user-defined 64-bit value from the object that was previously set via , or zero if none associated with the specified exists. + /// + virtual void get_private_data(const uint8_t guid[16], uint64_t *data) const = 0; + /// + /// Stores a user-defined 64-bit value in the object and associates it with the specified . + /// + /// + /// This function may NOT be called concurrently from multiple threads! + /// + virtual void set_private_data(const uint8_t guid[16], const uint64_t data) = 0; + + /// + /// Gets a reference to user-defined data from the object that was previously allocated via . + /// + template inline T &get_private_data() const + { + uint64_t res; + get_private_data(reinterpret_cast(&__uuidof(T)), &res); + return *reinterpret_cast(static_cast(res)); + } + /// + /// Allocates user-defined data and stores it in the object. + /// + template inline T &create_private_data() + { + uint64_t res = reinterpret_cast(new T()); + set_private_data(reinterpret_cast(&__uuidof(T)), res); + return *reinterpret_cast(static_cast(res)); + } + /// + /// Frees user-defined data that was previously allocated via . + /// + template inline void destroy_private_data() + { + uint64_t res; + get_private_data(reinterpret_cast(&__uuidof(T)), &res); + delete reinterpret_cast(static_cast(res)); + set_private_data(reinterpret_cast(&__uuidof(T)), 0); + } + }; + + /// + /// A logical render device, used for resource creation and global operations. + /// Functionally equivalent to a 'IDirect3DDevice9', 'ID3D10Device', 'ID3D11Device', 'ID3D12Device', 'HGLRC' or 'VkDevice'. + /// + /// + /// This class is safe to use concurrently from multiple threads in D3D10+ and Vulkan. + /// + struct __declspec(novtable) device : public api_object + { + /// + /// Gets the underlying graphics API used by this device. + /// + virtual device_api get_api() const = 0; + + /// + /// Checks whether the device supports the specified . + /// + virtual bool check_capability(device_caps capability) const = 0; + /// + /// Checks whether the specified texture supports the specified . + /// + virtual bool check_format_support(format format, resource_usage usage) const = 0; + + /// + /// Creates a new sampler state object. + /// + /// Description of the sampler to create. + /// Pointer to a variable that is set to the handle of the created sampler. + /// if the sampler was successfully created, otherwise (in this case is set to zero). + virtual bool create_sampler(const sampler_desc &desc, sampler *out_handle) = 0; + /// + /// Instantly destroys a sampler that was previously created via . + /// + virtual void destroy_sampler(sampler handle) = 0; + + /// + /// Allocates and creates a new resource. + /// + /// Description of the resource to create. + /// Optional data to upload to the resource after creation. This should point to an array of , one for each subresource (mipmap levels and array layers). Can be to indicate no initial data to upload. + /// Initial state of the resource after creation. This can later be changed via . + /// Pointer to a variable that is set to the handle of the created resource. + /// Optional pointer to a variable of type HANDLE used when contains . When that variable is a , it is set to the exported shared handle of the created resource. When that variable is a valid handle, the resource is imported from that shared handle. + /// if the resource was successfully created, otherwise (in this case is set to zero). + virtual bool create_resource(const resource_desc &desc, const subresource_data *initial_data, resource_usage initial_state, resource *out_handle, void **shared_handle = nullptr) = 0; + /// + /// Instantly destroys a resource that was previously created via and frees its memory. + /// Make sure the resource is no longer in use on the GPU (via any command list that may reference it and is still being executed) before doing this and never try to destroy resources created by the application! + /// + virtual void destroy_resource(resource handle) = 0; + + /// + /// Gets the description of the specified resource. + /// + virtual resource_desc get_resource_desc(resource resource) const = 0; + + /// + /// Creates a new resource view for the specified . + /// + /// Resource to create the view to. + /// Usage type of the resource view to create. Set to to create a shader resource view, for a depth-stencil view, for a render target etc. + /// Description of the resource view to create. + /// Pointer to a variable that is set to the handle of the created resource view. + /// if the resource view was successfully created, otherwise (in this case is set to zero). + virtual bool create_resource_view(resource resource, resource_usage usage_type, const resource_view_desc &desc, resource_view *out_handle) = 0; + /// + /// Instantly destroys a resource view that was previously created via . + /// + virtual void destroy_resource_view(resource_view handle) = 0; + + /// + /// Gets the handle to the underlying resource the specified resource was created for. + /// + /// + /// Resource views may be created without a resource in D3D12, which is used to initialize a null descriptor (reading zeroes, writes are discarded). This may therefore return zero for such views. + /// + virtual resource get_resource_from_view(resource_view view) const = 0; + /// + /// Gets the description of the specified resource view. + /// + virtual resource_view_desc get_resource_view_desc(resource_view view) const = 0; + + /// + /// Maps the memory of a buffer resource into application address space. + /// + /// Buffer resource to map to host memory. + /// Offset (in bytes) into the buffer resource to start mapping. + /// Number of bytes to map. Set to -1 (UINT64_MAX) to indicate that the entire buffer should be mapped. + /// Hint on how the returned data pointer will be accessed. + /// Pointer to a variable that is set to a pointer to the memory of the buffer resource. + /// if the memory of the buffer resource was successfully mapped, otherwise (in this case is set to ). + virtual bool map_buffer_region(resource resource, uint64_t offset, uint64_t size, map_access access, void **out_data) = 0; + /// + /// Unmaps a previously mapped buffer resource. + /// + /// Buffer resource to unmap from host memory. + virtual void unmap_buffer_region(resource resource) = 0; + /// + /// Maps the memory of a texture resource into application address space. + /// + /// Texture resource to map to host memory. + /// Index of the subresource to map (level + (layer * levels)). + /// Optional 3D box (or to reference the entire subresource) that defines the region in the to map. + /// Hint on how the returned data pointer will be accessed. + /// Pointer to a variable that is set to a pointer to the memory of the texture resource and optionally the row and slice pitch of that data (depending on the resource type). + /// if the memory of the texture resource was successfully mapped, otherwise (in this case is set to ). + virtual bool map_texture_region(resource resource, uint32_t subresource, const subresource_box *box, map_access access, subresource_data *out_data) = 0; + /// + /// Unmaps a previously mapped texture resource. + /// + /// Texture resource to unmap from host memory. + /// Index of the subresource to unmap (level + (layer * levels)). + virtual void unmap_texture_region(resource resource, uint32_t subresource) = 0; + + /// + /// Uploads data to a buffer resource. + /// + /// Pointer to the data to upload. + /// Buffer resource to upload to. + /// Offset (in bytes) into the buffer resource to start uploading to. + /// Number of bytes to upload. + virtual void update_buffer_region(const void *data, resource resource, uint64_t offset, uint64_t size) = 0; + /// + /// Uploads data to a texture resource. + /// + /// Pointer to the data to upload. + /// Texture resource to upload to. + /// Index of the subresource to upload to (level + (layer * levels)). + /// Optional 3D box (or to reference the entire subresource) that defines the region in the to upload to. + virtual void update_texture_region(const subresource_data &data, resource resource, uint32_t subresource, const subresource_box *box = nullptr) = 0; + + /// + /// Creates a new pipeline state object. + /// + /// Pipeline layout to use. + /// Number of sub-objects. + /// Pointer to an array of sub-objects that describe this pipeline. + /// Pointer to a variable that is set to the handle of the created pipeline state object. + /// if the pipeline state object was successfully created, otherwise (in this case is set to zero). + virtual bool create_pipeline(pipeline_layout layout, uint32_t subobject_count, const pipeline_subobject *subobjects, pipeline *out_handle) = 0; + /// + /// Instantly destroys a pipeline state object that was previously created via . + /// + virtual void destroy_pipeline(pipeline handle) = 0; + + /// + /// Creates a new pipeline layout. + /// + /// Number of layout parameters. + /// Pointer to an array of layout parameters that describe this pipeline layout. + /// Pointer to a variable that is set to the handle of the created pipeline layout. + /// if the pipeline layout was successfully created, otherwise (in this case is set to zero). + virtual bool create_pipeline_layout(uint32_t param_count, const pipeline_layout_param *params, pipeline_layout *out_handle) = 0; + /// + /// Instantly destroys a pipeline layout that was previously created via . + /// + virtual void destroy_pipeline_layout(pipeline_layout handle) = 0; + + /// + /// Allocates a descriptor table from an internal heap. + /// + /// Pipeline layout that contains a parameter that describes the descriptor table. + /// Index of the pipeline layout parameter that describes the descriptor table. + /// Pointer to a a variable that is set to the handles of the created descriptor table. + /// if the descriptor table was successfully allocated, otherwise (in this case is set to zeroe). + inline bool allocate_descriptor_table(pipeline_layout layout, uint32_t param, descriptor_table *out_handle) { return allocate_descriptor_tables(1, layout, param, out_handle); } + /// + /// Allocates one or more descriptor tables from an internal heap. + /// + /// Number of descriptor tables to allocate. + /// Pipeline layout that contains a parameter that describes the descriptor table. + /// Index of the pipeline layout parameter that describes the descriptor table. + /// Pointer to an array of handles with at least elements that is filled with the handles of the created descriptor tables. + /// if the descriptor tables were successfully allocated, otherwise (in this case is filled with zeroes). + virtual bool allocate_descriptor_tables(uint32_t count, pipeline_layout layout, uint32_t param, descriptor_table *out_handles) = 0; + /// + /// Frees a descriptor table that was previously allocated via . + /// + inline void free_descriptor_table(descriptor_table handle) { free_descriptor_tables(1, &handle); } + /// + /// Frees one or more descriptor tables that were previously allocated via . + /// + virtual void free_descriptor_tables(uint32_t count, const descriptor_table *handles) = 0; + + /// + /// Gets the offset (in descriptors) of the specified binding in the underlying descriptor heap of a descriptor table. + /// + /// Descriptor table to get the offset from. + /// Binding in the descriptor table to get the offset from. + /// Array index in the specified . + /// Pointer to a variable that is set to the handle of the underlying descriptor heap the was allocated from. + /// Pointer to a variable that is set to the offset of the binding in the underlying descriptor heap. + virtual void get_descriptor_heap_offset(descriptor_table table, uint32_t binding, uint32_t array_offset, descriptor_heap *out_heap, uint32_t *out_offset) const = 0; + + /// + /// Copies the contents of a descriptor table to another descriptor table. + /// + /// Descriptor table copy to process. + inline void copy_descriptors(const descriptor_table_copy ©) { copy_descriptor_tables(1, ©); } + /// + /// Copies the contents between multiple descriptor tables. + /// + /// Number of to process. + /// Pointer to an array of descriptor table copies to process. + virtual void copy_descriptor_tables(uint32_t count, const descriptor_table_copy *copies) = 0; + /// + /// Updates the contents of a descriptor table with the specified descriptors. + /// + /// Descriptor table update to process. + inline void update_descriptors(const descriptor_table_update &update) { update_descriptor_tables(1, &update); } + /// + /// Updates the contents of multiple descriptor tables with the specified descriptors. + /// + /// Number of to process. + /// Pointer to an array of descriptor table updates to process. + virtual void update_descriptor_tables(uint32_t count, const descriptor_table_update *updates) = 0; + + /// + /// Creates a new query heap. + /// + /// Type of queries that will be used with this query heap. + /// Number of queries to allocate in the query heap. + /// Pointer to a variable that is set to the handle of the created query heap. + /// if the query heap was successfully created, otherwise (in this case is set to zero). + virtual bool create_query_heap(query_type type, uint32_t size, query_heap *out_handle) = 0; + /// + /// Instantly destroys a query heap that was previously created via . + /// + virtual void destroy_query_heap(query_heap handle) = 0; + + /// + /// Gets the results of queries in a query heap. + /// + /// Query heap that contains the queries. + /// Index of the first query in the query heap to copy the results from. + /// Number of query results to copy. + /// Pointer to an array that is filled with the results. + /// Size (in bytes) of each element in the array. + /// if the query results were successfully downloaded from the GPU, otherwise. + virtual bool get_query_heap_results(query_heap heap, uint32_t first, uint32_t count, void *results, uint32_t stride) = 0; + + /// + /// Associates a name with a resource, for easier debugging in external tools. + /// + /// Resource to associate a name with. + /// Null-terminated name string. + virtual void set_resource_name(resource handle, const char *name) = 0; + /// + /// Associates a name with a resource view, for easier debugging in external tools. + /// + /// Resource view to associate a name with. + /// Null-terminated name string. + virtual void set_resource_view_name(resource_view handle, const char *name) = 0; + }; + + /// + /// The base class for objects that are children to a logical render . + /// + struct __declspec(novtable) device_object : public api_object + { + /// + /// Gets the parent device for this object. + /// + virtual device *get_device() = 0; + }; + + /// + /// The available indirect command types. + /// + enum class indirect_command + { + unknown, + draw, + draw_indexed, + dispatch + }; + + /// + /// A command list, used to enqueue render commands on the CPU, before later executing them in a command queue. + /// Functionally equivalent to a 'ID3D11CommandList', 'ID3D12CommandList' or 'VkCommandBuffer'. + /// + /// + /// This class may NOT be used concurrently from multiple threads! + /// + struct __declspec(novtable) command_list : public device_object + { + /// + /// Adds a barrier for the specified to the command stream. + /// When both and are a UAV barrier is added, otherwise a state transition is performed. + /// + /// Resource to transition. + /// Usage flags describing how the was used before this barrier. + /// Usage flags describing how the will be used after this barrier. + inline void barrier(resource resource, resource_usage old_state, resource_usage new_state) { barrier(1, &resource, &old_state, &new_state); } + /// + /// Adds a barrier for the specified to the command stream. + /// + /// Number of resources to transition. + /// Pointer to an array of resources to transition. + /// Pointer to an array of usage flags describing how the were used before this barrier. + /// Pointer to an array of usage flags describing how the will be used after this barrier. + virtual void barrier(uint32_t count, const resource *resources, const resource_usage *old_states, const resource_usage *new_states) = 0; + + /// + /// Begins a render pass and binds render target and depth-stencil resource views. + /// + /// Number of render target views to bind. + /// Pointer to an array of render target descriptions. + /// Optional pointer to a depth-stencil description, or to bind none. + virtual void begin_render_pass(uint32_t count, const render_pass_render_target_desc *rts, const render_pass_depth_stencil_desc *ds = nullptr) = 0; + /// + /// Ends a render pass. + /// This must be preceeded by a call to . + /// Render passes cannot be nested. + /// + virtual void end_render_pass() = 0; + /// + /// Binds individual render target and depth-stencil resource views. + /// This must not be called between and . + /// + /// + /// Number of render target views to bind. + /// Pointer to an array of render target views to bind. + /// Depth-stencil view to bind, or zero to bind none. + virtual void bind_render_targets_and_depth_stencil(uint32_t count, const resource_view *rtvs, resource_view dsv = { 0 }) = 0; + + /// + /// Binds a pipeline state object. + /// + /// Pipeline stages to update with state from the pipeline state object. + /// Pipeline state object to bind. + virtual void bind_pipeline(pipeline_stage stages, pipeline pipeline) = 0; + /// + /// Updates the specfified pipeline to the specified . + /// This is only valid for states that have been listed in the dynamic states provided at creation of the currently bound pipeline state object (). + /// + /// Pipeline state to update. + /// Value to update the pipeline state to. + inline void bind_pipeline_state(dynamic_state state, uint32_t value) { bind_pipeline_states(1, &state, &value); } + /// + /// Updates the specfified pipeline to the specified . + /// This is only valid for states that have been listed in the dynamic states provided at creation of the currently bound pipeline state object (). + /// + /// Number of pipeline states to update. + /// Pointer to an array of pipeline states to update. + /// Pointer to an array of values to update the pipeline states to, with one for each state in . + virtual void bind_pipeline_states(uint32_t count, const dynamic_state *states, const uint32_t *values) = 0; + /// + /// Binds an array of viewports to the rasterizer stage. + /// + /// + /// Index of the first viewport to bind. In D3D9, D3D10, D3D11 and D3D12 this has to be 0. + /// Number of viewports to bind. + /// Pointer to an array of viewports. + virtual void bind_viewports(uint32_t first, uint32_t count, const viewport *viewports) = 0; + /// + /// Binds an array of scissor rectangles to the rasterizer stage. + /// + /// + /// Index of the first scissor rectangle to bind. In D3D9, D3D10, D3D11 and D3D12 this has to be 0. + /// Number of scissor rectangles to bind. + /// Pointer to an array of scissor rectangles. + virtual void bind_scissor_rects(uint32_t first, uint32_t count, const rect *rects) = 0; + + /// + /// Directly updates constant values in the specified shader pipeline stages. + /// In D3D9 this updates the values of uniform registers, in D3D10/11 and OpenGL the constant buffer specified in the pipeline layout, in D3D12 it sets root constants and in Vulkan push constants. + /// + /// + /// Shader stages that will use the updated constants. + /// Pipeline layout that describes where the constants are located. + /// Layout parameter index of the constant range in the pipeline (root parameter index in D3D12). + /// Start offset (in 32-bit values) to the first constant in the constant range to begin updating. + /// Number of 32-bit values to update. + /// Pointer to an array of 32-bit values to set the constants to. These can be floating-point, integer or boolean depending on what the shader is expecting. + virtual void push_constants(shader_stage stages, pipeline_layout layout, uint32_t param, uint32_t first, uint32_t count, const void *values) = 0; + /// + /// Directly binds a temporary descriptor table for the specfified shader pipeline stage and updates with an array of descriptors. + /// + /// + /// Shader stages that will use the updated descriptors. + /// Pipeline layout that describes the descriptors. + /// Layout parameter index of the descriptor table in the pipeline (root parameter index in D3D12, descriptor set index in Vulkan). + /// Range of descriptors to update in the temporary descriptor table ( is ignored). + virtual void push_descriptors(shader_stage stages, pipeline_layout layout, uint32_t param, const descriptor_table_update &update) = 0; + /// + /// Binds a single descriptor table. + /// + /// Shader stages that will use the descriptors. + /// Pipeline layout that describes the descriptors. + /// Index of the pipeline parameter that describes the descriptor table (root parameter index in D3D12, descriptor set index in Vulkan). + /// Descriptor table to bind. + inline void bind_descriptor_table(shader_stage stages, pipeline_layout layout, uint32_t param, descriptor_table table) { bind_descriptor_tables(stages, layout, param, 1, &table); } + /// + /// Binds an array of descriptor tables. + /// + /// Shader stages that will use the descriptors. + /// Pipeline layout that describes the descriptors. + /// Index of the first pipeline parameter that describes the first descriptor table to bind (root parameter index in D3D12, descriptor set index in Vulkan). + /// Number of descriptor tables to bind. + /// Pointer to an array of descriptor tables to bind. + virtual void bind_descriptor_tables(shader_stage stages, pipeline_layout layout, uint32_t first, uint32_t count, const descriptor_table *tables) = 0; + + /// + /// Binds an index buffer to the input-assembler stage. + /// + /// Index buffer resource. This resource must have been created with the usage. + /// Offset (in bytes) from the start of the index buffer to the first index to use. In D3D9 this has to be 0. + /// Size (in bytes) of each index. Can typically be 2 (16-bit indices) or 4 (32-bit indices). + virtual void bind_index_buffer(resource buffer, uint64_t offset, uint32_t index_size) = 0; + /// + /// Binds a single vertex buffer to the input-assembler stage. + /// + /// Input slot for binding. + /// Vertex buffer resource. This resources must have been created with the usage. + /// Offset (in bytes) from the start of the vertex buffer to the first vertex element to use. + /// Size (in bytes) of the vertex element that will be used from the vertex buffer (is added to an element offset to advance to the next). + inline void bind_vertex_buffer(uint32_t index, resource buffer, uint64_t offset, uint32_t stride) { bind_vertex_buffers(index, 1, &buffer, &offset, &stride); } + /// + /// Binds an array of vertex buffers to the input-assembler stage. + /// + /// First input slot for binding. + /// Number of vertex buffers to bind. + /// Pointer to an array of vertex buffer resources. These resources must have been created with the usage. + /// Pointer to an array of offset values, one for each buffer. Each offset is the number of bytes from the start of the vertex buffer to the first vertex element to use. + /// Pointer to an array of stride values, one for each buffer. Each stride is the size (in bytes) of the vertex element that will be used from that vertex buffer (is added to an element offset to advance to the next). + virtual void bind_vertex_buffers(uint32_t first, uint32_t count, const resource *buffers, const uint64_t *offsets, const uint32_t *strides) = 0; + + /// + /// Binds an array of buffers to the stream-output stage. + /// + /// First stream-output slot for binding. + /// Number of stream-output targets to bind. + /// Pointer to an array of buffer resources. These resources must have been created with the usage. + /// Pointer to an array of offset values, one for each buffer. Each offset is the number of bytes from the start of the buffer to the first element to write to. + /// Optional pointer to an array of size values, one for each buffer. Can be or have elements set to UINT64_MAX to use the entire buffer. + /// Pointer to an array of counter buffer resources. These resources must have been created with the usage. + /// Pointer to an array of counter offset values, one for each counter buffer. Each offset is the number of bytes from the start of the counter buffer to the first element to write to. + virtual void bind_stream_output_buffers(uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint64_t *max_sizes, const api::resource *counter_buffers, const uint64_t *counter_offsets) = 0; + + /// + /// Draws non-indexed primitives. + /// + /// + /// Number of vertices to draw. + /// Number of instances to draw. In D3D9 this has to be 1. + /// Index of the first vertex. + /// Value added to each index before reading per-instance data from a vertex buffer. In D3D9 this has to be 0. + virtual void draw(uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) = 0; + /// + /// Draws indexed primitives. + /// + /// + /// Number of indices read from the index buffer for each instance. + /// Number of instances to draw. In D3D9 this has to be 1. + /// Location of the first index read from the index buffer. + /// Value added to each index before reading per-vertex data from a vertex buffer. + /// Value added to each index before reading per-instance data from a vertex buffer. In D3D9 this has to be 0. + virtual void draw_indexed(uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset, uint32_t first_instance) = 0; + /// + /// Performs a compute shader dispatch. + /// + /// + /// Number of thread groups dispatched in the x direction. + /// Number of thread groups dispatched in the y direction. + /// Number of thread groups dispatched in the z direction. + virtual void dispatch(uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z) = 0; + /// + /// Executes indirect draw or dispatch commands. + /// + /// + /// Specifies whether this is an indirect draw, indexed draw or dispatch command. + /// Buffer resource that contains command arguments. + /// Offset (in bytes) from the start of the argument buffer to the first argument to use. + /// Number of commands to execute. + /// Stride (in bytes) between commands in the argument buffer. + virtual void draw_or_dispatch_indirect(indirect_command type, resource buffer, uint64_t offset, uint32_t draw_count, uint32_t stride) = 0; + + /// + /// Copies the entire contents of the resource to the ination resource. Dimensions of the two resources have to match. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// Resource to copy from. + /// Resource to copy to. + virtual void copy_resource(resource source, resource dest) = 0; + /// + /// Copies a linear memory region from the buffer to the ination buffer. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// + /// Buffer resource to copy from. + /// Offset (in bytes) into the buffer to start copying at. + /// Buffer resource to copy to. + /// Offset (in bytes) into the ination buffer to start copying to. + /// Number of bytes to copy. + virtual void copy_buffer_region(resource source, uint64_t source_offset, resource dest, uint64_t dest_offset, uint64_t size) = 0; + /// + /// Copies a texture region from the buffer to the ination texture. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// + /// Buffer resource to copy from. + /// Offset (in bytes) into the buffer to start copying at. + /// Number of pixels from one row to the next (in the buffer), or zero if data is tightly packed. + /// Number of rows from one slice to the next (in the buffer) or zero if data is tightly packed. + /// Texture resource to copy to. + /// Index of the subresource of the ination texture to copy to. + /// Optional 3D box (or to reference the entire subresource) that defines the region in the ination texture to copy to. + virtual void copy_buffer_to_texture(resource source, uint64_t source_offset, uint32_t row_length, uint32_t slice_height, resource dest, uint32_t dest_subresource, const subresource_box *dest_box = nullptr) = 0; + /// + /// Copies or blits a texture region from the texture to the ination texture. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// + /// Texture resource to copy from. + /// Index of the subresource of the texture to copy from. + /// Optional 3D box (or to reference the entire subresource) that defines the region in the texture to blit from. + /// Texture resource to copy to. + /// Index of the subresource of the ination texture to copy to. + /// Optional 3D box (or to reference the entire subresource) that defines the region in the ination texture to blit to. + /// Filter to apply when copy requires scaling. + virtual void copy_texture_region(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint32_t dest_subresource, const subresource_box *dest_box, filter_mode filter = filter_mode::min_mag_mip_point) = 0; + /// + /// Copies a texture region from the texture to the ination buffer. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// + /// Texture resource to copy from. + /// Index of the subresource of the texture to copy from. + /// Optional 3D box (or to reference the entire subresource) that defines the region in the texture to copy from. + /// Buffer resource to copy to. + /// Offset (in bytes) into the ination buffer to start copying to. + /// Number of pixels from one row to the next (in the buffer), or zero if data is tightly packed. + /// Number of rows from one slice to the next (in the buffer), or zero if data is tightly packed. + virtual void copy_texture_to_buffer(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint64_t dest_offset, uint32_t row_length = 0, uint32_t slice_height = 0) = 0; + /// + /// Copies a region from the multisampled texture to the non-multisampled ination texture. + /// + /// + /// The resource has to be in the state. + /// The ination resource has to be in the state. + /// + /// + /// Texture resource to resolve from. + /// Index of the subresource of the texture to resolve from. + /// Optional 3D box (or to reference the entire subresource) that defines the region in the texture to resolve. + /// Texture resource to resolve to. + /// Index of the subresource of the ination texture to resolve to. + /// Optional X offset (in texels) that defines the region in the ination texture to resolve to. + /// Optional Y offset (in texels) that defines the region in the ination texture to resolve to. + /// Optional Z offset (in texels) that defines the region in the ination texture to resolve to. + /// Format of the resource data. + virtual void resolve_texture_region(resource source, uint32_t source_subresource, const subresource_box *source_box, resource dest, uint32_t dest_subresource, int32_t dest_x, int32_t dest_y, int32_t dest_z, format format) = 0; + + /// + /// Clears the resource referenced by the depth-stencil view. + /// + /// + /// The resource the depth-stencil view points to has to be in the state. + /// + /// Resource view handle of the depth-stencil. + /// Optional value to clear the depth buffer with. + /// Optional value to clear the stencil buffer with. + /// Number of rectangles to clear in the depth-stencil resource, or zero to clear the whole resource. + /// Pointer to an array of rectangles. + virtual void clear_depth_stencil_view(resource_view dsv, const float *depth, const uint8_t *stencil, uint32_t rect_count = 0, const rect *rects = nullptr) = 0; + /// + /// Clears the resource referenced by the render target view. + /// + /// + /// The resource the render target view points to has to be in the state. + /// + /// Resource view handle of the render target. + /// Value to clear the resource with. + /// Number of rectangles to clear in the render target resource, or zero to clear the whole resource. + /// Pointer to an array of rectangles. + virtual void clear_render_target_view(resource_view rtv, const float color[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0; + /// + /// Clears the resource referenced by the unordered access view. + /// + /// + /// The resource the unordered access view points to has to be in the state. + /// + /// Resource view handle of the unordered access view. + /// Value to clear the resource with. + /// Number of rectangles to clear in the unordered access resource, or zero to clear the whole resource. + /// Pointer to an array of rectangles. + virtual void clear_unordered_access_view_uint(resource_view uav, const uint32_t values[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0; + /// + /// Clears the resource referenced by the unordered access view. + /// + /// + /// The resource the unordered access view points to has to be in the state. + /// + /// Resource view handle of the unordered access view. + /// Value to clear the resource with. + /// Number of rectangles to clear in the unordered access resource, or zero to clear the whole resource. + /// Pointer to an array of rectangles. + virtual void clear_unordered_access_view_float(resource_view uav, const float values[4], uint32_t rect_count = 0, const rect *rects = nullptr) = 0; + + /// + /// Generates the lower mipmap levels for the specified shader resource view. + /// Uses the largest mipmap level of the view to recursively generate the lower levels of the mipmap chain and stops with the smallest level that is specified by the view. + /// + /// + /// This will invalidate all previous descriptor and pipeline bindings, which will need to be reset by calls to or and . + /// The resource the shader resource view points to has to be in the state and has to have been created with the flag. + /// + /// Shader resource view to update. + virtual void generate_mipmaps(resource_view srv) = 0; + + /// + /// Begins a query. + /// + /// Query heap that will manage the results of the query. + /// Type of the query to begin. + /// Index of the query in the query heap. + virtual void begin_query(query_heap heap, query_type type, uint32_t index) = 0; + /// + /// Ends a query. + /// + /// Query heap that will manage the results of the query. + /// Type of the query end. + /// Index of the query in the query heap. + virtual void end_query(query_heap heap, query_type type, uint32_t index) = 0; + /// + /// Copies the results of queries in a query heap to a buffer resource. + /// + /// + /// The ination resource has to be in the state. + /// + /// + /// Query heap that manages the results of the queries. + /// Type of the queries to copy. + /// Index of the first query in the query heap to copy the result from. + /// Number of query results to copy. + /// Buffer resource to copy to. + /// Offset (in bytes) into the ination buffer to start copying to. + /// Size (in bytes) of each result element. + virtual void copy_query_heap_results(query_heap heap, query_type type, uint32_t first, uint32_t count, resource dest, uint64_t dest_offset, uint32_t stride) = 0; + + /// + /// Opens a debug event region in the command list. + /// + /// Null-terminated string containing the label of the event. + /// Optional RGBA color value associated with the event. + virtual void begin_debug_event(const char *label, const float color[4] = nullptr) = 0; + /// + /// Closes the current debug event region (the last one opened with ). + /// + virtual void end_debug_event() = 0; + /// + /// Inserts a debug marker into the command list. + /// + /// Null-terminated string containing the label of the debug marker. + /// Optional RGBA color value associated with the debug marker. + virtual void insert_debug_marker(const char *label, const float color[4] = nullptr) = 0; + }; + + /// + /// A list of flags that represent the available command queue types, as returned by . + /// + enum class command_queue_type + { + graphics = 0x1, + compute = 0x2, + copy = 0x4 + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(command_queue_type); + + /// + /// A command queue, used to execute command lists on the GPU. + /// Functionally equivalent to the immediate 'ID3D11DeviceContext' or a 'ID3D12CommandQueue' or 'VkQueue'. + /// + /// + /// This class may NOT be used concurrently from multiple threads! + /// + struct __declspec(novtable) command_queue : public device_object + { + /// + /// Gets the type of the command queue, which specifies what commands can be executed on it. + /// + virtual command_queue_type get_type() const = 0; + + /// + /// Waits for all issued GPU operations on this queue to finish before returning. + /// This can be used to ensure that e.g. resources are no longer in use on the GPU before destroying them. + /// + virtual void wait_idle() const = 0; + + /// + /// Flushes and executes the special immediate command list returned by immediately. + /// This can be used to force commands to execute right away instead of waiting for the runtime to flush it automatically at some point. + /// + virtual void flush_immediate_command_list() const = 0; + + /// + /// Gets a special command list, on which all issued commands are executed as soon as possible (or right before the application executes its next command list on this queue). + /// This only exists on command queues that contain the flag, on other queues is returned. + /// + virtual command_list *get_immediate_command_list() = 0; + + /// + /// Opens a debug event region in the command queue. + /// + /// Null-terminated string containing the label of the event. + /// Optional RGBA color value associated with the event. + virtual void begin_debug_event(const char *label, const float color[4] = nullptr) = 0; + /// + /// Closes the current debug event region (the last one opened with ). + /// + virtual void end_debug_event() = 0; + /// + /// Inserts a debug marker into the command queue. + /// + /// Null-terminated string containing the label of the debug marker. + /// Optional RGBA color value associated with the debug marker. + virtual void insert_debug_marker(const char *label, const float color[4] = nullptr) = 0; + }; + + /// + /// Describes a swap chain and its back buffer resources. + /// + struct swapchain_desc + { + /// + /// Description of the back buffer resources. + /// + resource_desc back_buffer; + + /// + /// Number of back buffer resources in the swap chain. + /// + uint32_t back_buffer_count = 0; + + /// + /// Defines how the back buffers should be swapped when a present occurs. + /// Depending on the render API this can be a 'D3DSWAPEFFECT', 'DXGI_SWAP_EFFECT', 'WGL_SWAP_METHOD_ARB' or 'VkPresentModeKHR' value. + /// + uint32_t present_mode = 0; + + /// + /// Swap chain creation flags. + /// Depending on the render API this can be a 'D3DPRESENT', 'DXGI_PRESENT', 'PFD_*' or 'VkSwapchainCreateFlagsKHR' value. + /// + uint32_t present_flags = 0; + }; + + /// + /// A swap chain, used to present images to the screen. + /// Functionally equivalent to a 'IDirect3DSwapChain9', 'IDXGISwapChain', 'HDC' or 'VkSwapchainKHR'. + /// + struct __declspec(novtable) swapchain : public device_object + { + /// + /// Gets the handle of the window this swap chain was created with, or if this is an offscreen swap chain. + /// + virtual void *get_hwnd() const = 0; + + /// + /// Gets the back buffer resource at the specified in this swap chain. + /// + /// Index of the back buffer. This has to be between zero and the value returned by . + virtual resource get_back_buffer(uint32_t index) = 0; + + /// + /// Gets the number of back buffer resources in this swap chain. + /// + virtual uint32_t get_back_buffer_count() const = 0; + + /// + /// Gets the current back buffer resource. + /// + inline resource get_current_back_buffer() { return get_back_buffer(get_current_back_buffer_index()); } + /// + /// Gets the index of the back buffer resource that can currently be rendered into. + /// + virtual uint32_t get_current_back_buffer_index() const = 0; + }; +} } diff --git a/lib/reshade/include/reshade_api_format.hpp b/lib/reshade/include/reshade_api_format.hpp new file mode 100644 index 000000000..023b87e05 --- /dev/null +++ b/lib/reshade/include/reshade_api_format.hpp @@ -0,0 +1,460 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include +#include + +namespace reshade { namespace api +{ + /// + /// The available data and texture formats. + /// This is mostly compatible with 'DXGI_FORMAT'. + /// + enum class format : uint32_t + { + unknown = 0, + + // Color formats + + r1_unorm = 66, + l8_unorm = 0x3030384C, + a8_unorm = 65, + r8_typeless = 60, + r8_uint = 62, + r8_sint = 64, + r8_unorm = 61, + r8_snorm = 63, + l8a8_unorm = 0x3038414C, + r8g8_typeless = 48, + r8g8_uint = 50, + r8g8_sint = 52, + r8g8_unorm = 49, + r8g8_snorm = 51, + r8g8b8a8_typeless = 27, + r8g8b8a8_uint = 30, + r8g8b8a8_sint = 32, + r8g8b8a8_unorm = 28, + r8g8b8a8_unorm_srgb = 29, + r8g8b8a8_snorm = 31, + r8g8b8x8_unorm = 0x424757B9, + r8g8b8x8_unorm_srgb = 0x424757BA, + b8g8r8a8_typeless = 90, + b8g8r8a8_unorm = 87, + b8g8r8a8_unorm_srgb = 91, + b8g8r8x8_typeless = 92, + b8g8r8x8_unorm = 88, + b8g8r8x8_unorm_srgb = 93, + r10g10b10a2_typeless = 23, + r10g10b10a2_uint = 25, + r10g10b10a2_unorm = 24, + r10g10b10a2_xr_bias = 89, + b10g10r10a2_typeless = 0x42475330, + b10g10r10a2_uint = 0x42475332, + b10g10r10a2_unorm = 0x42475331, + l16_unorm = 0x3036314C, + r16_typeless = 53, + r16_uint = 57, + r16_sint = 59, + r16_unorm = 56, + r16_snorm = 58, + r16_float = 54, + l16a16_unorm = 0x3631414C, + r16g16_typeless = 33, + r16g16_uint = 36, + r16g16_sint = 38, + r16g16_unorm = 35, + r16g16_snorm = 37, + r16g16_float = 34, + r16g16b16a16_typeless = 9, + r16g16b16a16_uint = 12, + r16g16b16a16_sint = 14, + r16g16b16a16_unorm = 11, + r16g16b16a16_snorm = 13, + r16g16b16a16_float = 10, + r32_typeless = 39, + r32_uint = 42, + r32_sint = 43, + r32_float = 41, + r32g32_typeless = 15, + r32g32_uint = 17, + r32g32_sint = 18, + r32g32_float = 16, + r32g32b32_typeless = 5, + r32g32b32_uint = 7, + r32g32b32_sint = 8, + r32g32b32_float = 6, + r32g32b32a32_typeless = 1, + r32g32b32a32_uint = 3, + r32g32b32a32_sint = 4, + r32g32b32a32_float = 2, + r9g9b9e5 = 67, + r11g11b10_float = 26, + b5g6r5_unorm = 85, + b5g5r5a1_unorm = 86, + b5g5r5x1_unorm = 0x424757B5, + b4g4r4a4_unorm = 115, + a4b4g4r4_unorm = 191, + + // Depth-stencil formats + + s8_uint = 0x30303853, + d16_unorm = 55, + d16_unorm_s8_uint = 0x38363144, + d24_unorm_x8_uint = 0x38343244, + d24_unorm_s8_uint = 45, + d32_float = 40, + d32_float_s8_uint = 20, + + r24_g8_typeless = 44, + r24_unorm_x8_uint = 46, + x24_unorm_g8_uint = 47, + r32_g8_typeless = 19, + r32_float_x8_uint = 21, + x32_float_g8_uint = 22, + + // Compressed data formats + + bc1_typeless = 70, + bc1_unorm = 71, + bc1_unorm_srgb = 72, + bc2_typeless = 73, + bc2_unorm = 74, + bc2_unorm_srgb = 75, + bc3_typeless = 76, + bc3_unorm = 77, + bc3_unorm_srgb = 78, + bc4_typeless = 79, + bc4_unorm = 80, + bc4_snorm = 81, + bc5_typeless = 82, + bc5_unorm = 83, + bc5_snorm = 84, + bc6h_typeless = 94, + bc6h_ufloat = 95, + bc6h_sfloat = 96, + bc7_typeless = 97, + bc7_unorm = 98, + bc7_unorm_srgb = 99, + + // Video formats + + r8g8_b8g8_unorm = 68, + g8r8_g8b8_unorm = 69, + + // Special purpose formats + + intz = 0x5A544E49, + }; + + /// + /// The available color space types for presentation. + /// + enum class color_space : uint32_t + { + unknown = 0, + + srgb_nonlinear, + extended_srgb_linear, + hdr10_st2084, + hdr10_hlg, + }; + + /// + /// Converts the specified format to its equivalent typeless variant. + /// + /// The format to convert. + inline format format_to_typeless(format value) + { + switch (value) + { + case format::l8_unorm: + case format::r8_typeless: + case format::r8_uint: + case format::r8_sint: + case format::r8_unorm: + case format::r8_snorm: + return format::r8_typeless; + case format::l8a8_unorm: + case format::r8g8_typeless: + case format::r8g8_uint: + case format::r8g8_sint: + case format::r8g8_unorm: + case format::r8g8_snorm: + return format::r8g8_typeless; + case format::r8g8b8a8_typeless: + case format::r8g8b8a8_uint: + case format::r8g8b8a8_sint: + case format::r8g8b8a8_unorm: + case format::r8g8b8a8_unorm_srgb: + case format::r8g8b8a8_snorm: + case format::r8g8b8x8_unorm: + case format::r8g8b8x8_unorm_srgb: + return format::r8g8b8a8_typeless; + case format::b8g8r8a8_typeless: + case format::b8g8r8a8_unorm: + case format::b8g8r8a8_unorm_srgb: + return format::b8g8r8a8_typeless; + case format::b8g8r8x8_typeless: + case format::b8g8r8x8_unorm: + case format::b8g8r8x8_unorm_srgb: + return format::b8g8r8x8_typeless; + case format::r10g10b10a2_typeless: + case format::r10g10b10a2_uint: + case format::r10g10b10a2_unorm: + case format::r10g10b10a2_xr_bias: + return format::r10g10b10a2_typeless; + case format::b10g10r10a2_typeless: + case format::b10g10r10a2_uint: + case format::b10g10r10a2_unorm: + return format::b10g10r10a2_typeless; + case format::l16_unorm: + case format::d16_unorm: + case format::r16_typeless: + case format::r16_uint: + case format::r16_sint: + case format::r16_float: + case format::r16_unorm: + case format::r16_snorm: + return format::r16_typeless; + case format::l16a16_unorm: + case format::r16g16_typeless: + case format::r16g16_uint: + case format::r16g16_sint: + case format::r16g16_float: + case format::r16g16_unorm: + case format::r16g16_snorm: + return format::r16g16_typeless; + case format::r16g16b16a16_typeless: + case format::r16g16b16a16_uint: + case format::r16g16b16a16_sint: + case format::r16g16b16a16_float: + case format::r16g16b16a16_unorm: + case format::r16g16b16a16_snorm: + return format::r16g16b16a16_typeless; + case format::d32_float: + case format::r32_typeless: + case format::r32_uint: + case format::r32_sint: + case format::r32_float: + return format::r32_typeless; + case format::r32g32_typeless: + case format::r32g32_uint: + case format::r32g32_sint: + case format::r32g32_float: + return format::r32g32_typeless; + case format::r32g32b32_typeless: + case format::r32g32b32_uint: + case format::r32g32b32_sint: + case format::r32g32b32_float: + return format::r32g32b32_typeless; + case format::r32g32b32a32_typeless: + case format::r32g32b32a32_uint: + case format::r32g32b32a32_sint: + case format::r32g32b32a32_float: + return format::r32g32b32a32_typeless; + case format::d32_float_s8_uint: + case format::r32_g8_typeless: + case format::r32_float_x8_uint: + case format::x32_float_g8_uint: + return format::r32_g8_typeless; + case format::d24_unorm_s8_uint: // Do not also convert 'd24_unorm_x8_uint' here, to keep it distinguishable from 'd24_unorm_s8_uint' + case format::r24_g8_typeless: + case format::r24_unorm_x8_uint: + case format::x24_unorm_g8_uint: + return format::r24_g8_typeless; + case format::bc1_typeless: + case format::bc1_unorm: + case format::bc1_unorm_srgb: + return format::bc1_typeless; + case format::bc2_typeless: + case format::bc2_unorm: + case format::bc2_unorm_srgb: + return format::bc2_typeless; + case format::bc3_typeless: + case format::bc3_unorm: + case format::bc3_unorm_srgb: + return format::bc2_typeless; + case format::bc4_typeless: + case format::bc4_unorm: + case format::bc4_snorm: + return format::bc4_typeless; + case format::bc5_typeless: + case format::bc5_unorm: + case format::bc5_snorm: + return format::bc5_typeless; + case format::bc6h_typeless: + case format::bc6h_ufloat: + case format::bc6h_sfloat: + return format::bc6h_typeless; + case format::bc7_typeless: + case format::bc7_unorm: + case format::bc7_unorm_srgb: + return format::bc7_typeless; + default: + return value; + } + } + + /// + /// Converts the specified format to its equivalent typed variant ("unorm" or "float"). + /// + /// The format to convert. + /// Set to 1 to get sRGB variant, 0 to get linear variant and -1 to preserve existing one. + inline format format_to_default_typed(format value, int srgb_variant = -1) + { + switch (value) + { + case format::r8_typeless: + return format::r8_unorm; + case format::r8g8_typeless: + return format::r8g8_unorm; + case format::r8g8b8a8_typeless: + case format::r8g8b8a8_unorm: + return srgb_variant == 1 ? format::r8g8b8a8_unorm_srgb : format::r8g8b8a8_unorm; + case format::r8g8b8a8_unorm_srgb: + return srgb_variant != 0 ? format::r8g8b8a8_unorm_srgb : format::r8g8b8a8_unorm; + case format::r8g8b8x8_unorm: + return srgb_variant == 1 ? format::r8g8b8x8_unorm_srgb : format::r8g8b8x8_unorm; + case format::r8g8b8x8_unorm_srgb: + return srgb_variant != 0 ? format::r8g8b8x8_unorm_srgb : format::r8g8b8x8_unorm; + case format::b8g8r8a8_typeless: + case format::b8g8r8a8_unorm: + return srgb_variant == 1 ? format::b8g8r8a8_unorm_srgb : format::b8g8r8a8_unorm; + case format::b8g8r8a8_unorm_srgb: + return srgb_variant != 0 ? format::b8g8r8a8_unorm_srgb : format::b8g8r8a8_unorm; + case format::b8g8r8x8_typeless: + case format::b8g8r8x8_unorm: + return srgb_variant == 1 ? format::b8g8r8x8_unorm_srgb : format::b8g8r8x8_unorm; + case format::b8g8r8x8_unorm_srgb: + return srgb_variant != 0 ? format::b8g8r8x8_unorm_srgb : format::b8g8r8x8_unorm; + case format::r10g10b10a2_typeless: + return format::r10g10b10a2_unorm; + case format::b10g10r10a2_typeless: + return format::b10g10r10a2_unorm; + case format::d16_unorm: + case format::r16_typeless: + return format::r16_float; + case format::r16g16_typeless: + return format::r16g16_float; + case format::r16g16b16a16_typeless: + return format::r16g16b16a16_float; + case format::d32_float: + case format::r32_typeless: + return format::r32_float; + case format::r32g32_typeless: + return format::r32g32_float; + case format::r32g32b32_typeless: + return format::r32g32b32_float; + case format::r32g32b32a32_typeless: + return format::r32g32b32a32_float; + case format::d32_float_s8_uint: + case format::r32_g8_typeless: + return format::r32_float_x8_uint; + case format::d24_unorm_s8_uint: // Do not also convert 'd24_unorm_x8_uint' here, to keep it distinguishable from 'd24_unorm_s8_uint' + case format::r24_g8_typeless: + return format::r24_unorm_x8_uint; + case format::bc1_typeless: + case format::bc1_unorm: + return srgb_variant == 1 ? format::bc1_unorm_srgb : format::bc1_unorm; + case format::bc1_unorm_srgb: + return srgb_variant != 0 ? format::bc1_unorm_srgb : format::bc1_unorm; + case format::bc2_typeless: + case format::bc2_unorm: + return srgb_variant == 1 ? format::bc2_unorm_srgb : format::bc2_unorm; + case format::bc2_unorm_srgb: + return srgb_variant != 0 ? format::bc2_unorm_srgb : format::bc2_unorm; + case format::bc3_typeless: + case format::bc3_unorm: + return srgb_variant == 1 ? format::bc3_unorm_srgb : format::bc3_unorm; + case format::bc3_unorm_srgb: + return srgb_variant != 0 ? format::bc3_unorm_srgb : format::bc3_unorm; + case format::bc4_typeless: + return format::bc4_unorm; + case format::bc5_typeless: + return format::bc5_unorm; + case format::bc6h_typeless: + return format::bc6h_ufloat; + case format::bc7_typeless: + case format::bc7_unorm: + return srgb_variant == 1 ? format::bc7_unorm_srgb : format::bc7_unorm; + case format::bc7_unorm_srgb: + return srgb_variant != 0 ? format::bc7_unorm_srgb : format::bc7_unorm; + default: + return value; + } + } + + /// + /// Converts the specified format to its equivalent depth-stencil variant. + /// + /// The format to convert. + inline format format_to_depth_stencil_typed(format value) + { + switch (value) + { + case format::r16_typeless: + case format::r16_unorm: + return format::d16_unorm; + case format::r32_typeless: + case format::r32_float: + return format::d32_float; + case format::r32_g8_typeless: + case format::r32_float_x8_uint: + case format::x32_float_g8_uint: + return format::d32_float_s8_uint; + case format::r24_g8_typeless: + case format::r24_unorm_x8_uint: + case format::x24_unorm_g8_uint: + return format::d24_unorm_s8_uint; + default: + return value; + } + } + + /// + /// Gets the number of bytes a texture row of the specified format occupies. + /// + inline const uint32_t format_row_pitch(format value, uint32_t width) + { + if (value == format::unknown) + return 0; + + if (value <= format::r32g32b32a32_sint) + return 16 * width; + if (value <= format::r32g32b32_sint) + return 12 * width; + if (value <= format::x32_float_g8_uint) + return 8 * width; + if (value <= format::x24_unorm_g8_uint || value == format::l16a16_unorm) + return 4 * width; + if (value <= format::r16_sint || value == format::b5g6r5_unorm || value == format::b5g5r5a1_unorm || value == format::b5g5r5x1_unorm || value == format::l8a8_unorm || value == format::l16_unorm) + return 2 * width; + if (value <= format::a8_unorm || value == format::l8_unorm) + return 1 * width; + if (value <= format::g8r8_g8b8_unorm || (value >= format::b8g8r8a8_unorm && value <= format::b8g8r8x8_unorm_srgb) || (value == format::r8g8b8x8_unorm || value == format::r8g8b8x8_unorm_srgb)) + return 4 * width; + + // Block compressed formats are bytes per block, rather than per pixel + if ((value >= format::bc1_typeless && value <= format::bc1_unorm_srgb) || (value >= format::bc4_typeless && value <= format::bc4_snorm)) + return 8 * ((width + 3) / 4); + if ((value >= format::bc2_typeless && value <= format::bc2_unorm_srgb) || (value >= format::bc3_typeless && value <= format::bc3_unorm_srgb) || (value >= format::bc5_typeless && value <= format::bc7_unorm_srgb)) + return 16 * ((width + 3) / 4); + + return 0; + } + + /// + /// Gets the number of bytes a texture slice of the specified format occupies. + /// + inline const uint32_t format_slice_pitch(format value, uint32_t row_pitch, uint32_t height) + { + if ((value >= format::bc1_typeless && value <= format::bc5_snorm) || (value >= format::bc6h_typeless && value <= format::bc7_unorm_srgb)) + return row_pitch * ((height + 3) / 4); + + return row_pitch * height; + } +} } diff --git a/lib/reshade/include/reshade_api_pipeline.hpp b/lib/reshade/include/reshade_api_pipeline.hpp new file mode 100644 index 000000000..51601617d --- /dev/null +++ b/lib/reshade/include/reshade_api_pipeline.hpp @@ -0,0 +1,1001 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include "reshade_api_resource.hpp" + +namespace reshade { namespace api +{ + /// + /// A list of flags that represent the available shader stages in the render pipeline. + /// + enum class shader_stage : uint32_t + { + vertex = 0x1, + hull = 0x2, + domain = 0x4, + geometry = 0x8, + pixel = 0x10, + compute = 0x20, + + all = 0x7FFFFFFF, + all_compute = compute, + all_graphics = vertex | hull | domain | geometry | pixel + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(shader_stage); + + /// + /// A list of flags that represent the available pipeline stages in the render pipeline. + /// + enum class pipeline_stage : uint32_t + { + vertex_shader = 0x8, + hull_shader = 0x10, + domain_shader = 0x20, + geometry_shader = 0x40, + pixel_shader = 0x80, + compute_shader = 0x800, + + input_assembler = 0x2, + stream_output = 0x4, + rasterizer = 0x100, + depth_stencil = 0x200, + output_merger = 0x400, + + all = 0x7FFFFFFF, + all_compute = compute_shader, + all_graphics = vertex_shader | hull_shader | domain_shader | geometry_shader | pixel_shader | input_assembler | stream_output | rasterizer | depth_stencil | output_merger, + all_shader_stages = vertex_shader | hull_shader | domain_shader | geometry_shader | pixel_shader | compute_shader + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(pipeline_stage); + + /// + /// The available descriptor types. + /// + enum class descriptor_type : uint32_t + { + sampler = 0, + sampler_with_resource_view = 1, + shader_resource_view = 2, + unordered_access_view = 3, + constant_buffer = 6, + shader_storage_buffer = 7 + }; + + /// + /// The available pipeline layout parameter types. + /// + enum class pipeline_layout_param_type : uint32_t + { + push_constants = 1, + descriptor_table = 0, + push_descriptors = 2, + push_descriptors_with_ranges = 3 + }; + + /// + /// Describes a range of constants in a pipeline layout. + /// + struct constant_range + { + /// + /// OpenGL uniform buffer binding index. + /// + uint32_t binding = 0; + /// + /// D3D10/D3D11/D3D12 constant buffer register index. + /// + uint32_t dx_register_index = 0; + /// + /// D3D12 constant buffer register space. + /// + uint32_t dx_register_space = 0; + /// + /// Number of constants in this range (in 32-bit values). + /// + uint32_t count = 0; + /// + /// Shader pipeline stages that can make use of the constants in this range. + /// + shader_stage visibility = shader_stage::all; + }; + + /// + /// Describes a range of descriptors of a descriptor table in a pipeline layout. + /// + struct descriptor_range + { + /// + /// OpenGL/Vulkan binding index (layout(binding=X) in GLSL). + /// In D3D this is equivalent to the offset (in descriptors) of this range in the descriptor table (since each binding can only have an array size of 1). + /// + uint32_t binding = 0; + /// + /// D3D9/D3D10/D3D11/D3D12 shader register index (register(xX) in HLSL). + /// + uint32_t dx_register_index = 0; + /// + /// D3D12 register space (register(..., spaceX) in HLSL). + /// + uint32_t dx_register_space = 0; + /// + /// Number of descriptors in this range. + /// Set to -1 (UINT32_MAX) to indicate an unbounded range. + /// + uint32_t count = 0; + /// + /// Shader pipeline stages that can make use of the descriptors in this range. + /// + shader_stage visibility = shader_stage::all; + /// + /// Size of the array in case this is an array binding. + /// Only meaningful in Vulkan, in OpenGL and other APIs this has to be 1 (since each array element is a separate binding there). + /// If this is less than the total number of descriptors specified in , then the remaining descriptors are assigned a separate binding (with an array size of 1), with the binding index incrementing with each additional descriptor. + /// + uint32_t array_size = 1; + /// + /// Type of the descriptors in this range. + /// + descriptor_type type = descriptor_type::sampler; + }; + + /// + /// Describes a single parameter in a pipeline layout. + /// + struct pipeline_layout_param + { + constexpr pipeline_layout_param() : push_descriptors() {} + constexpr pipeline_layout_param(const constant_range &push_constants) : type(pipeline_layout_param_type::push_constants), push_constants(push_constants) {} + constexpr pipeline_layout_param(const descriptor_range &push_descriptors) : type(pipeline_layout_param_type::push_descriptors), push_descriptors(push_descriptors) {} + constexpr pipeline_layout_param(uint32_t count, const descriptor_range *ranges) : type(pipeline_layout_param_type::descriptor_table), descriptor_table({ count, ranges }) {} + + /// + /// Type of the parameter. + /// + pipeline_layout_param_type type = pipeline_layout_param_type::push_descriptors; + + union + { + /// + /// Used when parameter type is . + /// + constant_range push_constants; + + /// + /// Used when parameter type is . + /// + descriptor_range push_descriptors; + + /// + /// Used when parameter type is or . + /// + struct + { + uint32_t count; + const descriptor_range *ranges; + } descriptor_table; + }; + }; + + /// + /// An opaque handle to a pipeline layout object. + /// In D3D12 this is a pointer to a 'ID3D12RootSignature' object, in Vulkan a 'VkPipelineLayout' handle. + /// + RESHADE_DEFINE_HANDLE(pipeline_layout); + + /// + /// The fill mode to use when rendering triangles. + /// + enum class fill_mode : uint32_t + { + solid = 0, + wireframe = 1, + point = 2 + }; + + /// + /// Indicates triangles facing a particular direction are not drawn. + /// + enum class cull_mode : uint32_t + { + none = 0, + front = 1, + back = 2, + front_and_back = front | back + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(cull_mode); + + /// + /// The available logic operations. + /// + enum class logic_op : uint32_t + { + clear = 0, + bitwise_and = 1, + bitwise_and_reverse = 2, + copy = 3, + bitwise_and_inverted = 4, + noop = 5, + bitwise_xor = 6, + bitwise_or = 7, + bitwise_nor = 8, + equivalent = 9, + invert = 10, + bitwise_or_reverse = 11, + copy_inverted = 12, + bitwise_or_inverted = 13, + bitwise_nand = 14, + set = 15 + }; + + /// + /// The available color or alpha blending operations. + /// + enum class blend_op : uint32_t + { + add = 0, + subtract = 1, + reverse_subtract = 2, + min = 3, + max = 4 + }; + + /// + /// The available blend factors in color or alpha blending operations. + /// + enum class blend_factor : uint32_t + { + zero = 0, + one = 1, + source_color = 2, + one_minus_source_color = 3, + dest_color = 4, + one_minus_dest_color = 5, + source_alpha = 6, + one_minus_source_alpha = 7, + dest_alpha = 8, + one_minus_dest_alpha = 9, + constant_color = 10, + one_minus_constant_color = 11, + constant_alpha = 12, + one_minus_constant_alpha = 13, + source_alpha_saturate = 14, + source1_color = 15, + one_minus_source1_color = 16, + source1_alpha = 17, + one_minus_source1_alpha = 18 + }; + + /// + /// The available stencil operations that can be performed during depth-stencil testing. + /// + enum class stencil_op : uint32_t + { + keep = 0, + zero = 1, + replace = 2, + increment_saturate = 3, + decrement_saturate = 4, + invert = 5, + increment = 6, + decrement = 7 + }; + + /// + /// Specifies how the pipeline interprets vertex data that is bound to the vertex input stage and subsequently renders it. + /// + enum class primitive_topology : uint32_t + { + undefined = 0, + + point_list = 1, + line_list = 2, + line_strip = 3, + triangle_list = 4, + triangle_strip = 5, + triangle_fan = 6, + quad_list = 8, + quad_strip = 9, + line_list_adj = 10, + line_strip_adj = 11, + triangle_list_adj = 12, + triangle_strip_adj = 13, + + patch_list_01_cp = 33, + patch_list_02_cp, + patch_list_03_cp, + patch_list_04_cp, + patch_list_05_cp, + patch_list_06_cp, + patch_list_07_cp, + patch_list_08_cp, + patch_list_09_cp, + patch_list_10_cp, + patch_list_11_cp, + patch_list_12_cp, + patch_list_13_cp, + patch_list_14_cp, + patch_list_15_cp, + patch_list_16_cp, + patch_list_17_cp, + patch_list_18_cp, + patch_list_19_cp, + patch_list_20_cp, + patch_list_21_cp, + patch_list_22_cp, + patch_list_23_cp, + patch_list_24_cp, + patch_list_25_cp, + patch_list_26_cp, + patch_list_27_cp, + patch_list_28_cp, + patch_list_29_cp, + patch_list_30_cp, + patch_list_31_cp, + patch_list_32_cp + }; + + /// + /// Describes a shader object. + /// + struct shader_desc + { + /// + /// Shader source code or binary. + /// + const void *code = nullptr; + /// + /// Size (in bytes) of the shader source or binary. + /// + size_t code_size = 0; + /// + /// Optional entry point name if the shader source or binary contains multiple entry points. + /// Can be if it does not, or to use the default "main" entry point. + /// + const char *entry_point = nullptr; + + /// + /// Number of entries in the and arrays. + /// This is meaningful only when the shader binary is a SPIR-V module and is ignored otherwise. + /// + uint32_t spec_constants = 0; + /// + /// Pointer to an array of specialization constant indices. + /// + const uint32_t *spec_constant_ids = nullptr; + /// + /// Pointer to an array of constant values, one for each specialization constant index in . + /// + const uint32_t *spec_constant_values = nullptr; + }; + + /// + /// Describes a single element in the vertex layout for the input-assembler stage. + /// + struct input_element + { + /// + /// GLSL attribute location associated with this element (layout(location = X)). + /// + uint32_t location = 0; + /// + /// HLSL semantic associated with this element. + /// + const char *semantic = nullptr; + /// + /// Optional index for the HLSL semantic (e.g. for "TEXCOORD1" set to "TEXCOORD" and to 1). + /// + uint32_t semantic_index = 0; + /// + /// Format of the element data. + /// + format format = format::unknown; + /// + /// Index of the vertex buffer binding. + /// + uint32_t buffer_binding = 0; + /// + /// Offset (in bytes) from the start of the vertex to this element. + /// + uint32_t offset = 0; + /// + /// Stride of the entire vertex (this has to be consistent for all elements per vertex buffer binding). + /// Set to zero in case this is unknown. + /// + uint32_t stride = 0; + /// + /// Number of instances to draw using the same per-instance data before advancing by one element. + /// This has to be consistent for all elements per vertex buffer binding. + /// Set to zero to indicate that this element is per-vertex rather than per-instance. + /// + uint32_t instance_step_rate = 0; + }; + + /// + /// Describes the state of the stream-output stage. + /// + struct stream_output_desc + { + /// + /// Index of the stream output stream to be sent to the rasterizer stage. + /// + uint32_t rasterized_stream = 0; + }; + + /// + /// Describes the state of the output-merger stage. + /// + struct blend_desc + { + /// + /// Use alpha-to-coverage as a multisampling technique when setting a pixel to a render target. + /// + bool alpha_to_coverage_enable = false; + /// + /// Enable or disable blending for each render target. + /// + /// + bool blend_enable[8] = { false, false, false, false, false, false, false, false }; + /// + /// Enable or disable a logical operation for each render target. + /// + /// + bool logic_op_enable[8] = { false, false, false, false, false, false, false, false }; + /// + /// Source to use for the RGB value that the pixel shader outputs. + /// + /// + blend_factor source_color_blend_factor[8] = { blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one }; + /// + /// Destination to use for the current RGB value in the render target. + /// + /// + blend_factor dest_color_blend_factor[8] = { blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero }; + /// + /// Operation to use to combine and . + /// + /// + blend_op color_blend_op[8] = { blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add }; + /// + /// Source to use for the alpha value that the pixel shader outputs. + /// + /// + blend_factor source_alpha_blend_factor[8] = { blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one, blend_factor::one }; + /// + /// Destination to use for the current alpha value in the render target. + /// + /// + blend_factor dest_alpha_blend_factor[8] = { blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero, blend_factor::zero }; + /// + /// Operation to use to combine and . + /// + /// + blend_op alpha_blend_op[8] = { blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add, blend_op::add }; + /// + /// Constant RGBA value to use when or is . + /// + float blend_constant[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + /// + /// Logical operation for each render target. Ignored if is . + /// + /// + logic_op logic_op[8] = { logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop, logic_op::noop }; + /// + /// A write mask specifying which color components are written to each render target. Bitwise combination of 0x1 for red, 0x2 for green, 0x4 for blue and 0x8 for alpha. + /// + uint8_t render_target_write_mask[8] = { 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF }; + }; + + /// + /// Describes the state of the rasterizer stage. + /// + struct rasterizer_desc + { + /// + /// Fill mode to use when rendering triangles. + /// + /// + fill_mode fill_mode = fill_mode::solid; + /// + /// Triangles facing the specified direction are not drawn. + /// + cull_mode cull_mode = cull_mode::back; + /// + /// Determines if a triangle is front or back-facing. + /// + bool front_counter_clockwise = false; + /// + /// Depth value added to a given pixel. + /// + float depth_bias = 0.0f; + /// + /// Maximum depth bias of a pixel. + /// + float depth_bias_clamp = 0.0f; + /// + /// Scalar on the slope of a given pixel. + /// + float slope_scaled_depth_bias = 0.0f; + /// + /// Enable or disable clipping based on distance. + /// + bool depth_clip_enable = true; + /// + /// Enable or disable scissor testing (scissor rectangle culling). + /// + bool scissor_enable = false; + /// + /// Use the quadrilateral or alpha line anti-aliasing algorithm on multisample antialiasing render targets. + /// + bool multisample_enable = false; + /// + /// Enable or disable line antialiasing. Only applies if doing line drawing and is . + /// + bool antialiased_line_enable = false; + /// + /// Enable or disable conservative rasterization mode. + /// + /// + uint32_t conservative_rasterization = 0; + }; + + /// + /// Describes the state of the depth-stencil stage. + /// + struct depth_stencil_desc + { + /// + /// Enable or disable depth testing. + /// + bool depth_enable = true; + /// + /// Enable or disable writes to the depth-stencil buffer. + /// + bool depth_write_mask = true; + /// + /// Comparison function to use to compare new depth value from a fragment against current depth value in the depth-stencil buffer. + /// + compare_op depth_func = compare_op::less; + /// + /// Enable or disable stencil testing. + /// + bool stencil_enable = false; + /// + /// Mask applied to stencil values read from the depth-stencil buffer for pixels whose surface normal is towards the camera. + /// + uint8_t front_stencil_read_mask = 0xFF; + /// + /// Mask applied to stencil values written to the depth-stencil buffer for pixels whose surface normal is towards the camera. + /// + uint8_t front_stencil_write_mask = 0xFF; + /// + /// Reference value to perform against when stencil testing pixels whose surface normal is towards the camera. + /// + uint8_t front_stencil_reference_value = 0; + /// + /// Comparison function to use to compare new stencil value from a fragment against current stencil value for pixels whose surface normal is facing towards the camera. + /// + compare_op front_stencil_func = compare_op::always; + /// + /// Stencil operation to perform when stencil testing and depth testing both pass for pixels whose surface normal is facing towards the camera. + /// + stencil_op front_stencil_pass_op = stencil_op::keep; + /// + /// Stencil operation to perform when stencil testing fails for pixels whose surface normal is towards the camera. + /// + stencil_op front_stencil_fail_op = stencil_op::keep; + /// + /// Stencil operation to perform when stencil testing passes and depth testing fails for pixels whose surface normal is facing towards the camera. + /// + stencil_op front_stencil_depth_fail_op = stencil_op::keep; + /// + /// Mask applied to stencil values read from the depth-stencil buffer for pixels whose surface normal is facing away from the camera. + /// + uint8_t back_stencil_read_mask = 0xFF; + /// + /// Mask applied to stencil values written to the depth-stencil buffer for pixels whose surface normal is facing away from the camera. + /// + uint8_t back_stencil_write_mask = 0xFF; + /// + /// Reference value to perform against when stencil testing pixels whose surface normal is facing away from the camera. + /// + uint8_t back_stencil_reference_value = 0; + /// + /// Comparison function to use to compare new stencil value from a fragment against current stencil value for pixels whose surface normal is facing away from the camera. + /// + compare_op back_stencil_func = compare_op::always; + /// + /// Stencil operation to perform when stencil testing and depth testing both pass for pixels whose surface normal is facing away from the camera. + /// + stencil_op back_stencil_pass_op = stencil_op::keep; + /// + /// Stencil operation to perform when stencil testing fails for pixels whose surface normal is facing away from the camera. + /// + stencil_op back_stencil_fail_op = stencil_op::keep; + /// + /// Stencil operation to perform when stencil testing passes and depth testing fails for pixels whose surface normal is facing away from the camera. + /// + stencil_op back_stencil_depth_fail_op = stencil_op::keep; + }; + + /// + /// The available pipeline sub-object types. + /// + enum class pipeline_subobject_type : uint32_t + { + unknown, + + /// + /// Vertex shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + vertex_shader, + /// + /// Hull shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + hull_shader, + /// + /// Domain shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + domain_shader, + /// + /// Geometry shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + geometry_shader, + /// + /// Pixel shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + pixel_shader, + /// + /// Compute shader to use. + /// Sub-object data is a pointer to a . + /// + /// + /// + compute_shader, + /// + /// Vertex layout for the input-assembler stage. + /// Sub-object data is a pointer to an array of . + /// + /// + input_layout, + /// + /// State of the stream-output stage. + /// Sub-object data is a pointer to a . + /// + /// + stream_output_state, + /// + /// State of the output-merger stage. + /// Sub-object data is a pointer to a . + /// + /// + blend_state, + /// + /// State of the rasterizer stage. + /// Sub-object data is a pointer to a . + /// + /// + rasterizer_state, + /// + /// State of the depth-stencil stage. + /// Sub-object data is a pointer to a . + /// + /// + depth_stencil_state, + /// + /// Primitive topology to use when rendering. + /// Sub-object data is a pointer to a value. + /// + primitive_topology, + /// + /// Format of the depth-stencil view that may be used with this pipeline. + /// Sub-object data is a pointer to a value. + /// + depth_stencil_format, + /// + /// Formats of the render target views that may be used with this pipeline. + /// Sub-object data is a pointer to an array of values. + /// + render_target_formats, + /// + /// Mask applied to the coverage mask for a fragment during rasterization. + /// Sub-object data is a pointer to a 32-bit unsigned integer value. + /// + sample_mask, + /// + /// Number of samples used in rasterization. + /// Sub-object data is a pointer to a 32-bit unsigned integer value. + /// + sample_count, + /// + /// Maximum number of viewports that may be bound via with this pipeline. + /// Sub-object data is a pointer to a 32-bit unsigned integer value. + /// + viewport_count, + /// + /// States that may be dynamically updated via after binding this pipeline. + /// Sub-object data is a pointer to an array of values. + /// + dynamic_pipeline_states, + /// + /// Maximum number of vertices a draw call with this pipeline will draw. + /// Sub-object data is a pointer to a 32-bit unsigned integer value. + /// + max_vertex_count + }; + + /// + /// Describes a pipeline sub-object. + /// + struct pipeline_subobject + { + /// + /// Type of the specified sub-object . + /// + pipeline_subobject_type type = pipeline_subobject_type::unknown; + /// + /// Number of sub-object descriptions. + /// This should usually be 1, except for array sub-objects like (where this specifies the number of render targets) or . + /// + uint32_t count = 0; + /// + /// Pointer to an array of sub-object descriptions (which should be as large as the specified ). + /// Depending on the sub-object this should be a pointer to a , , , or ... + /// + void *data = nullptr; + }; + + /// + /// An opaque handle to a pipeline state object. + /// In D3D9, D3D10, D3D11 or D3D12 this is a pointer to a 'IDirect3D(...)Shader', 'ID3D10(...)(Shader/State)', 'ID3D11(...)(Shader/State)' or 'ID3D12PipelineState' object, in Vulkan a 'VkPipeline' handle. + /// + RESHADE_DEFINE_HANDLE(pipeline); + + /// + /// A constant buffer resource descriptor. + /// + struct buffer_range + { + /// + /// Constant buffer resource. + /// + resource buffer = { 0 }; + /// + /// Offset from the start of the buffer resource (in bytes). + /// + uint64_t offset = 0; + /// + /// Number of elements this range covers in the buffer resource (in bytes). + /// Set to -1 (UINT64_MAX) to indicate that the whole buffer should be used. + /// + uint64_t size = UINT64_MAX; + }; + + /// + /// A combined sampler and resource view descriptor. + /// + struct sampler_with_resource_view + { + /// + /// Sampler to sampler the shader resource view with. + /// + sampler sampler = { 0 }; + /// + /// Shader resource view. + /// + resource_view view = { 0 }; + }; + + /// + /// An opaque handle to a descriptor table in a descriptor heap. + /// In Vulkan this is a 'VkDescriptorSet' handle. + /// + RESHADE_DEFINE_HANDLE(descriptor_table); + + /// + /// All information needed to copy descriptors between descriptor tables. + /// + struct descriptor_table_copy + { + /// + /// Descriptor table to copy from. + /// + descriptor_table source_table = { 0 }; + /// + /// Index of the binding in the source descriptor table. + /// + uint32_t source_binding = 0; + /// + /// Array index in the specified source binding to begin copying from. + /// + uint32_t source_array_offset = 0; + /// + /// Descriptor table to copy to. + /// + descriptor_table dest_table = { 0 }; + /// + /// Index of the binding in the destination descriptor table. + /// + uint32_t dest_binding = 0; + /// + /// Array index in the specified destination binding to begin copying to. + /// + uint32_t dest_array_offset = 0; + /// + /// Number of descriptors to copy. + /// + uint32_t count = 0; + }; + + /// + /// All information needed to update descriptors in a descriptor table. + /// + struct descriptor_table_update + { + /// + /// Descriptor table to update. + /// + descriptor_table table = { 0 }; + /// + /// OpenGL/Vulkan binding index in the descriptor set. + /// In D3D this is equivalent to the offset (in descriptors) from the start of the table. + /// + uint32_t binding = 0; + /// + /// Array index in the specified to begin updating at. + /// Only meaningful in Vulkan, in OpenGL and other APIs this has to be 0 (since each array element gets a separate binding). + /// + uint32_t array_offset = 0; + /// + /// Number of descriptors to update, starting at the specified . + /// If the specified has fewer than array elements starting from , then the remainder will be used to update the subsequent binding starting at array element zero, recursively. + /// + uint32_t count = 0; + /// + /// Type of the specified . + /// + descriptor_type type = descriptor_type::sampler; + /// + /// Pointer to an array of descriptors to update in the descriptor table (which should be as large as the specified ). + /// Depending on the descriptor this should be pointer to an array of , , or . + /// + const void *descriptors = nullptr; + }; + + /// + /// An opaque handle to a descriptor heap. + /// In D3D12 this is a pointer to a 'ID3D12DescriptorHeap' object, in Vulkan a 'VkDescriptorPool' handle. + /// + RESHADE_DEFINE_HANDLE(descriptor_heap); + + /// + /// The available query types. + /// + enum class query_type + { + occlusion = 0, + binary_occlusion = 1, + timestamp = 2, + pipeline_statistics = 3, + stream_output_statistics_0 = 4, + stream_output_statistics_1, + stream_output_statistics_2, + stream_output_statistics_3 + }; + + /// + /// An opaque handle to a query heap. + /// In D3D12 this is a pointer to a 'ID3D12QueryHeap' object, in Vulkan a 'VkQueryPool' handle. + /// + RESHADE_DEFINE_HANDLE(query_heap); + + /// + /// A list of all possible render pipeline states that can be set independent of pipeline state objects. + /// Support for these varies between render APIs (e.g. modern APIs like D3D12 and Vulkan support much less dynamic states than D3D9). + /// + enum class dynamic_state + { + unknown = 0, + + alpha_test_enable = 15, + alpha_reference_value = 24, + alpha_func = 25, + srgb_write_enable = 194, + primitive_topology = 1000, + sample_mask = 162, + + // Blend state + + alpha_to_coverage_enable = 1003, + blend_enable = 27, + logic_op_enable = 1004, + source_color_blend_factor = 19, + dest_color_blend_factor = 20, + color_blend_op = 171, + source_alpha_blend_factor = 207, + dest_alpha_blend_factor = 208, + alpha_blend_op = 209, + blend_constant = 193, + logic_op = 1005, + render_target_write_mask = 168, + + // Rasterizer state + + fill_mode = 8, + cull_mode = 22, + front_counter_clockwise = 1001, + depth_bias = 195, + depth_bias_clamp = 1002, + depth_bias_slope_scaled = 175, + depth_clip_enable = 136, + scissor_enable = 174, + multisample_enable = 161, + antialiased_line_enable = 176, + + // Depth-stencil state + + depth_enable = 7, + depth_write_mask = 14, + depth_func = 23, + stencil_enable = 52, + front_stencil_read_mask = 58, + front_stencil_write_mask = 59, + front_stencil_reference_value = 57, + front_stencil_func = 56, + front_stencil_pass_op = 55, + front_stencil_fail_op = 53, + front_stencil_depth_fail_op = 54, + back_stencil_read_mask = 1006, + back_stencil_write_mask = 1007, + back_stencil_reference_value = 1008, + back_stencil_func = 189, + back_stencil_pass_op = 188, + back_stencil_fail_op = 186, + back_stencil_depth_fail_op = 187, + }; + + /// + /// Describes a rectangle. + /// + struct rect + { + int32_t left = 0; + int32_t top = 0; + int32_t right = 0; + int32_t bottom = 0; + + constexpr uint32_t width() const { return right - left; } + constexpr uint32_t height() const { return bottom - top; } + }; + + /// + /// Describes a render viewport. + /// + struct viewport + { + float x = 0.0f; + float y = 0.0f; + float width = 0.0f; + float height = 0.0f; + float min_depth = 0.0f; + float max_depth = 1.0f; + }; +} } diff --git a/lib/reshade/include/reshade_api_resource.hpp b/lib/reshade/include/reshade_api_resource.hpp new file mode 100644 index 000000000..9da2df04f --- /dev/null +++ b/lib/reshade/include/reshade_api_resource.hpp @@ -0,0 +1,528 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#define RESHADE_DEFINE_HANDLE(name) \ + typedef struct { uint64_t handle; } name; \ + constexpr bool operator< (name lhs, name rhs) { return lhs.handle < rhs.handle; } \ + constexpr bool operator!=(name lhs, name rhs) { return lhs.handle != rhs.handle; } \ + constexpr bool operator!=(name lhs, uint64_t rhs) { return lhs.handle != rhs; } \ + constexpr bool operator==(name lhs, name rhs) { return lhs.handle == rhs.handle; } \ + constexpr bool operator==(name lhs, uint64_t rhs) { return lhs.handle == rhs; } + +#define RESHADE_DEFINE_ENUM_FLAG_OPERATORS(type) \ + constexpr type operator~(type a) { return static_cast(~static_cast(a)); } \ + inline type &operator&=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) &= static_cast(b)); } \ + constexpr type operator&(type a, type b) { return static_cast(static_cast(a) & static_cast(b)); } \ + inline type &operator|=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) |= static_cast(b)); } \ + constexpr type operator|(type a, type b) { return static_cast(static_cast(a) | static_cast(b)); } \ + inline type &operator^=(type &a, type b) { return reinterpret_cast(reinterpret_cast(a) ^= static_cast(b)); } \ + constexpr type operator^(type a, type b) { return static_cast(static_cast(a) ^ static_cast(b)); } \ + constexpr bool operator==(type lhs, uint32_t rhs) { return static_cast(lhs) == rhs; } \ + constexpr bool operator!=(type lhs, uint32_t rhs) { return static_cast(lhs) != rhs; } + +#include "reshade_api_format.hpp" + +namespace reshade { namespace api +{ + /// + /// The available comparison types. + /// + enum class compare_op : uint32_t + { + never = 0, + less = 1, + equal = 2, + less_equal = 3, + greater = 4, + not_equal = 5, + greater_equal = 6, + always = 7 + }; + + /// + /// The available filtering modes used for texture sampling operations. + /// + enum class filter_mode : uint32_t + { + min_mag_mip_point = 0, + min_mag_point_mip_linear = 0x1, + min_point_mag_linear_mip_point = 0x4, + min_point_mag_mip_linear = 0x5, + min_linear_mag_mip_point = 0x10, + min_linear_mag_point_mip_linear = 0x11, + min_mag_linear_mip_point = 0x14, + min_mag_mip_linear = 0x15, + min_mag_anisotropic_mip_point = 0x54, + anisotropic = 0x55, + compare_min_mag_mip_point = 0x80, + compare_min_mag_point_mip_linear = 0x81, + compare_min_point_mag_linear_mip_point = 0x84, + compare_min_point_mag_mip_linear = 0x85, + compare_min_linear_mag_mip_point = 0x90, + compare_min_linear_mag_point_mip_linear = 0x91, + compare_min_mag_linear_mip_point = 0x94, + compare_min_mag_mip_linear = 0x95, + compare_min_mag_anisotropic_mip_point = 0xd4, + compare_anisotropic = 0xd5 + }; + + /// + /// Specifies behavior of sampling with texture coordinates outside a texture resource. + /// + enum class texture_address_mode : uint32_t + { + wrap = 1, + mirror = 2, + clamp = 3, + border = 4, + mirror_once = 5 + }; + + /// + /// Describes a sampler state. + /// + struct sampler_desc + { + /// + /// Filtering mode to use when sampling a texture. + /// + filter_mode filter = filter_mode::min_mag_mip_linear; + /// + /// Method to use for resolving U texture coordinates outside 0 to 1 range. + /// + texture_address_mode address_u = texture_address_mode::clamp; + /// + /// Method to use for resolving V texture coordinates outside 0 to 1 range. + /// + texture_address_mode address_v = texture_address_mode::clamp; + /// + /// Method to use for resolving W texture coordinates outside 0 to 1 range. + /// + texture_address_mode address_w = texture_address_mode::clamp; + /// + /// Offset applied to the calculated mipmap level when sampling a texture. + /// + float mip_lod_bias = 0.0f; + /// + /// Clamping value to use when filtering mode is . + /// + float max_anisotropy = 1.0f; + /// + /// Comparison function to use to compare sampled data against existing sampled data. + /// + compare_op compare_op = compare_op::never; + /// + /// RGBA value to return for texture coordinates outside 0 to 1 range when addressing mode is . + /// + float border_color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + /// + /// Lower end of the mipmap range to clamp access to. + /// + float min_lod = -FLT_MAX; + /// + /// Upper end of the mipmap range to clamp access to. + /// + float max_lod = +FLT_MAX; + }; + + /// + /// An opaque handle to a sampler state object. + /// Depending on the render API this can be a pointer to a 'ID3D10SamplerState', 'ID3D11SamplerState' or a 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a sampler descriptor) or 'VkSampler' handle. + /// + RESHADE_DEFINE_HANDLE(sampler); + + /// + /// The available memory mapping access types. + /// + enum class map_access + { + read_only = 1, + write_only, + read_write, + write_discard + }; + + /// + /// The available memory heap types, which give a hint as to where to place the memory allocation for a resource. + /// + enum class memory_heap : uint32_t + { + unknown, // Usually indicates a resource that is reserved, but not yet bound to any memory. + gpu_only, + // Upload heap + cpu_to_gpu, + // Readback heap + gpu_to_cpu, + cpu_only, + custom + }; + + /// + /// The available resource types. The type of a resource is specified during creation and is immutable. + /// Various operations may have special requirements on the type of resources they operate on (e.g. copies can only happen between resources of the same type, ...). + /// + enum class resource_type : uint32_t + { + unknown, + buffer, + texture_1d, + texture_2d, + texture_3d, + surface // Special type for resources that are implicitly both resource and render target view. + }; + + /// + /// A list of flags that describe additional parameters of a resource. + /// + enum class resource_flags : uint32_t + { + none = 0, + dynamic = (1 << 3), + cube_compatible = (1 << 2), + generate_mipmaps = (1 << 0), + shared = (1 << 1), + shared_nt_handle = (1 << 11), + structured = (1 << 6), + sparse_binding = (1 << 18) + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_flags); + + /// + /// A list of flags that specify how a resource is to be used. + /// This needs to be specified during creation and is also used to transition between different resource states within a command list. + /// + enum class resource_usage : uint32_t + { + undefined = 0, + + index_buffer = 0x2, + vertex_buffer = 0x1, + constant_buffer = 0x8000, + stream_output = 0x100, + indirect_argument = 0x200, + + depth_stencil = 0x30, + depth_stencil_read = 0x20, + depth_stencil_write = 0x10, + render_target = 0x4, + shader_resource = 0xC0, + shader_resource_pixel = 0x80, + shader_resource_non_pixel = 0x40, + unordered_access = 0x8, + + copy_dest = 0x400, + copy_source = 0x800, + resolve_dest = 0x1000, + resolve_source = 0x2000, + + // The following are special resource states and may only be used in barriers: + + general = 0x80000000, + present = 0x80000000 | render_target | copy_source, + cpu_access = vertex_buffer | index_buffer | shader_resource | indirect_argument | copy_source + }; + RESHADE_DEFINE_ENUM_FLAG_OPERATORS(resource_usage); + + /// + /// Describes a resource, such as a buffer or texture. + /// + struct [[nodiscard]] resource_desc + { + constexpr resource_desc() : texture() {} + constexpr resource_desc(uint64_t size, memory_heap heap, resource_usage usage) : + type(resource_type::buffer), buffer({ size }), heap(heap), usage(usage) {} + constexpr resource_desc(uint32_t width, uint32_t height, uint16_t layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) : + type(resource_type::texture_2d), texture({ width, height, layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {} + constexpr resource_desc(resource_type type, uint32_t width, uint32_t height, uint16_t depth_or_layers, uint16_t levels, format format, uint16_t samples, memory_heap heap, resource_usage usage, resource_flags flags = resource_flags::none) : + type(type), texture({ width, height, depth_or_layers, levels, format, samples }), heap(heap), usage(usage), flags(flags) {} + + /// + /// Type of the resource. + /// + resource_type type = resource_type::unknown; + + union + { + /// + /// Used when resource type is a buffer. + /// + struct + { + /// + /// Size of the buffer (in bytes). + /// + uint64_t size = 0; + /// + /// Structure stride for structured buffers (in bytes), otherwise zero. + /// + uint32_t stride = 0; + } buffer; + + /// + /// Used when resource type is a texture or surface. + /// + struct + { + /// + /// Width of the texture (in texels). + /// + uint32_t width = 1; + /// + /// If this is a 2D or 3D texture, height of the texture (in texels), otherwise 1. + /// + uint32_t height = 1; + /// + /// If this is a 3D texture, depth of the texture (in texels), otherwise number of array layers. + /// + uint16_t depth_or_layers = 1; + /// + /// Maximum number of mipmap levels in the texture, including the base level, so at least 1. + /// Can also be zero in case the exact number of mipmap levels is unknown. + /// + uint16_t levels = 1; + /// + /// Data format of each texel in the texture. + /// + format format = format::unknown; + /// + /// The number of samples per texel. Set to a value higher than 1 for multisampling. + /// + uint16_t samples = 1; + } texture; + }; + + /// + /// Memory heap the resource allocation is placed in. + /// + memory_heap heap = memory_heap::unknown; + /// + /// Flags that specify how this resource may be used. + /// + resource_usage usage = resource_usage::undefined; + /// + /// Flags that describe additional parameters. + /// + resource_flags flags = resource_flags::none; + }; + + /// + /// An opaque handle to a resource object (buffer, texture, ...). + /// Resources created by the application are only guaranteed to be valid during event callbacks. + /// Depending on the render API this can be a pointer to a 'IDirect3DResource9', 'ID3D10Resource', 'ID3D11Resource' or 'ID3D12Resource' object or a 'VkImage' handle. + /// + RESHADE_DEFINE_HANDLE(resource); + + /// + /// The available resource view types. These identify how a resource view interprets the data of its resource. + /// + enum class resource_view_type : uint32_t + { + unknown, + buffer, + texture_1d, + texture_1d_array, + texture_2d, + texture_2d_array, + texture_2d_multisample, + texture_2d_multisample_array, + texture_3d, + texture_cube, + texture_cube_array + }; + + /// + /// Describes a resource view, which specifies how to interpret the data of a resource. + /// + struct [[nodiscard]] resource_view_desc + { + constexpr resource_view_desc() : texture() {} + constexpr resource_view_desc(format format, uint64_t offset, uint64_t size) : + type(resource_view_type::buffer), format(format), buffer({ offset, size }) {} + constexpr resource_view_desc(format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) : + type(resource_view_type::texture_2d), format(format), texture({ first_level, levels, first_layer, layers }) {} + constexpr resource_view_desc(resource_view_type type, format format, uint32_t first_level, uint32_t levels, uint32_t first_layer, uint32_t layers) : + type(type), format(format), texture({ first_level, levels, first_layer, layers }) {} + constexpr explicit resource_view_desc(format format) : type(resource_view_type::texture_2d), format(format), texture({ 0, 1, 0, 1 }) {} + + /// + /// Resource type the view should interpret the resource data to. + /// + resource_view_type type = resource_view_type::unknown; + /// + /// Format the view should reinterpret the resource data to (can be different than the format of the resource as long as they are compatible). + /// + format format = format::unknown; + + union + { + /// + /// Used when view type is a buffer. + /// + struct + { + /// + /// Offset from the start of the buffer resource (in bytes). + /// + uint64_t offset = 0; + /// + /// Number of elements this view covers in the buffer resource (in bytes). + /// Set to -1 (UINT64_MAX) to indicate that the entire buffer resource should be used. + /// + uint64_t size = UINT64_MAX; + } buffer; + + /// + /// Used when view type is a texture. + /// + struct + { + /// + /// Index of the most detailed mipmap level to use. This number has to be between zero and the maximum number of mipmap levels in the texture minus 1. + /// + uint32_t first_level = 0; + /// + /// Maximum number of mipmap levels for the view of the texture. + /// Set to -1 (UINT32_MAX) to indicate that all mipmap levels down to the least detailed should be used. + /// + uint32_t level_count = UINT32_MAX; + /// + /// Index of the first array layer of the texture array to use. This value is ignored if the texture is not layered. + /// + uint32_t first_layer = 0; + /// + /// Maximum number of array layers for the view of the texture array. This value is ignored if the texture is not layered. + /// Set to -1 (UINT32_MAX) to indicate that all array layers should be used. + /// + uint32_t layer_count = UINT32_MAX; + } texture; + }; + }; + + /// + /// An opaque handle to a resource view object (depth-stencil, render target, shader resource view, ...). + /// Resource views created by the application are only guaranteed to be valid during event callbacks. + /// Depending on the render API this can be a pointer to a 'IDirect3DResource9', 'ID3D10View' or 'ID3D11View' object, or a 'D3D12_CPU_DESCRIPTOR_HANDLE' (to a view descriptor) or 'VkImageView' handle. + /// + RESHADE_DEFINE_HANDLE(resource_view); + + /// + /// Describes a region inside a subresource. + /// + struct subresource_box + { + int32_t left = 0; + int32_t top = 0; + int32_t front = 0; + int32_t right = 0; + int32_t bottom = 0; + int32_t back = 0; + + constexpr uint32_t width() const { return right - left; } + constexpr uint32_t height() const { return bottom - top; } + constexpr uint32_t depth() const { return back - front; } + }; + + /// + /// Describes the data of a subresource. + /// + struct subresource_data + { + /// + /// Pointer to the data. + /// + void *data = nullptr; + /// + /// Row pitch of the data (added to the data pointer to move between texture rows, unused for buffers and 1D textures). + /// + /// + uint32_t row_pitch = 0; + /// + /// Depth pitch of the data (added to the data pointer to move between texture depth/array slices, unused for buffers and 1D/2D textures). + /// + /// + uint32_t slice_pitch = 0; + }; + + /// + /// Specifies how the contents of a render target or depth-stencil view are treated at the start of a render pass. + /// + enum class render_pass_load_op : uint32_t + { + load, + clear, + discard, + no_access + }; + + /// + /// Specifies how the contents of a render target or depth-stencil view are treated at the end of a render pass. + /// + enum class render_pass_store_op : uint32_t + { + store, + discard, + no_access + }; + + /// + /// Describes a depth-stencil view and how it is treated at the start and end of a render pass. + /// + struct render_pass_depth_stencil_desc + { + /// + /// Depth-stencil resource view. + /// + resource_view view = { 0 }; + /// + /// Specifies how the depth contents of the depth-stencil view are treated at the start of the render pass. + /// + render_pass_load_op depth_load_op = render_pass_load_op::load; + /// + /// Specifies how the depth contents of the depth-stencil view are treated at the end of the render pass. + /// + render_pass_store_op depth_store_op = render_pass_store_op::store; + /// + /// Specifies how the stencil contents of the depth-stencil view are treated at the start of the render pass. + /// + render_pass_load_op stencil_load_op = render_pass_load_op::load; + /// + /// Specifies how the stencil contents of the depth-stencil view are treated at the end of the render pass. + /// + render_pass_store_op stencil_store_op = render_pass_store_op::store; + /// + /// Value the depth contents of the depth-stencil resource is cleared to when is . + /// + float clear_depth = 0.0f; + /// + /// Value the stencil contents of the depth-stencil resource is cleared to when is . + /// + uint8_t clear_stencil = 0; + }; + + /// + /// Describes a render target view and how it is treated at the start and end of a render pass. + /// + struct render_pass_render_target_desc + { + /// + /// Render target resource view. + /// + resource_view view = { 0 }; + /// + /// Specifies how the contents of the render target view are treated at the start of the render pass. + /// + render_pass_load_op load_op = render_pass_load_op::load; + /// + /// Specifies how the contents of the render target view are treated at the end of the render pass. + /// + render_pass_store_op store_op = render_pass_store_op::store; + /// + /// Value the render target resource is cleared to when is . + /// + float clear_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + }; +} } diff --git a/lib/reshade/include/reshade_events.hpp b/lib/reshade/include/reshade_events.hpp new file mode 100644 index 000000000..52eeb61b1 --- /dev/null +++ b/lib/reshade/include/reshade_events.hpp @@ -0,0 +1,1696 @@ +/* + * Copyright (C) 2021 Patrick Mours + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#pragma once + +#include "reshade_api.hpp" + +namespace reshade +{ + enum class addon_event : uint32_t + { + /// + /// Called after successfull device creation, from: + /// + /// IDirect3D9::CreateDevice + /// IDirect3D9Ex::CreateDeviceEx + /// IDirect3DDevice9::Reset + /// IDirect3DDevice9Ex::ResetEx + /// D3D10CreateDevice + /// D3D10CreateDevice1 + /// D3D10CreateDeviceAndSwapChain + /// D3D10CreateDeviceAndSwapChain1 + /// D3D11CreateDevice + /// D3D11CreateDeviceAndSwapChain + /// D3D12CreateDevice + /// glMakeCurrent + /// vkCreateDevice + /// + /// Callback function signature: void (api::device *device) + /// + init_device, + + /// + /// Called on device destruction, before: + /// + /// IDirect3DDevice9::Reset + /// IDirect3DDevice9Ex::ResetEx + /// IDirect3DDevice9::Release + /// ID3D10Device::Release + /// ID3D11Device::Release + /// ID3D12Device::Release + /// wglDeleteContext + /// vkDestroyDevice + /// + /// Callback function signature: void (api::device *device) + /// + destroy_device, + + /// + /// Called after successfull command list creation, from: + /// + /// ID3D11Device::CreateDeferredContext + /// ID3D11Device1::CreateDeferredContext1 + /// ID3D11Device2::CreateDeferredContext2 + /// ID3D11Device3::CreateDeferredContext3 + /// ID3D12Device::CreateCommandList + /// ID3D12Device4::CreateCommandList1 + /// vkAllocateCommandBuffers + /// + /// Callback function signature: void (api::command_list *cmd_list) + /// + /// + /// In case of D3D9, D3D10, D3D11 and OpenGL this is called during device initialization as well and behaves as if an implicit immediate command list was created. + /// + init_command_list, + + /// + /// Called on command list destruction, before: + /// + /// ID3D11CommandList::Release + /// ID3D12CommandList::Release + /// vkFreeCommandBuffers + /// + /// Callback function signature: void (api::command_list *cmd_list) + /// + destroy_command_list, + + /// + /// Called after successfull command queue creation, from: + /// + /// ID3D12Device::CreateCommandQueue + /// vkCreateDevice (for every queue associated with the device) + /// + /// Callback function signature: void (api::command_queue *queue) + /// + /// + /// In case of D3D9, D3D10, D3D11 and OpenGL this is called during device initialization as well and behaves as if an implicit command queue was created. + /// + init_command_queue, + + /// + /// Called on command queue destruction, before: + /// + /// ID3D12CommandQueue::Release + /// vkDestroyDevice (for every queue associated with the device) + /// + /// Callback function signature: void (api::command_queue *queue) + /// + destroy_command_queue, + + /// + /// Called after successfull swap chain creation, from: + /// + /// IDirect3D9::CreateDevice (for the implicit swap chain) + /// IDirect3D9Ex::CreateDeviceEx (for the implicit swap chain) + /// IDirect3D9Device::CreateAdditionalSwapChain + /// IDirect3DDevice9::Reset (for the implicit swap chain) + /// IDirect3DDevice9Ex::ResetEx (for the implicit swap chain) + /// IDXGIFactory::CreateSwapChain + /// IDXGIFactory2::CreateSwapChain(...) + /// IDXGISwapChain::ResizeBuffers + /// IDXGISwapChain3::ResizeBuffers1 + /// wglMakeCurrent + /// wglSwapBuffers (after window was resized) + /// vkCreateSwapchainKHR + /// + /// Callback function signature: void (api::swapchain *swapchain) + /// + init_swapchain, + + /// + /// Called on swap chain creation, before: + /// + /// IDirect3D9::CreateDevice (for the implicit swap chain) + /// IDirect3D9Ex::CreateDeviceEx (for the implicit swap chain) + /// IDirect3D9Device::CreateAdditionalSwapChain + /// IDirect3D9Device::Reset (for the implicit swap chain) + /// IDirect3D9DeviceEx::ResetEx (for the implicit swap chain) + /// IDXGIFactory::CreateSwapChain + /// IDXGIFactory2::CreateSwapChain(...) + /// IDXGISwapChain::ResizeBuffers + /// IDXGISwapChain3::ResizeBuffers1 + /// wglSetPixelFormat + /// vkCreateSwapchainKHR + /// + /// Callback function signature: bool (api::swapchain_desc &desc, void *hwnd) + /// + /// + /// To overwrite the swap chain description, modify desc in the callback and return , otherwise return . + /// + create_swapchain, + + /// + /// Called on swap chain destruction, before: + /// + /// IDirect3DDevice9::Release (for the implicit swap chain) + /// IDirect3DSwapChain9::Release + /// IDXGISwapChain::Release + /// wglDeleteContext + /// wglSwapBuffers (after window was resized) + /// vkDestroySwapchainKHR + /// + /// In addition, called when swap chain is reset, before: + /// + /// IDirect3DDevice9::Reset (for the implicit swap chain) + /// IDirect3DDevice9Ex::ResetEx (for the implicit swap chain) + /// IDXGISwapChain::ResizeBuffers + /// IDXGISwapChain1::ResizeBuffers1 + /// + /// Callback function signature: void (api::swapchain *swapchain) + /// + destroy_swapchain, + + /// + /// Called after effect runtime initialization (which happens after swap chain creation or a swap chain buffer resize). + /// Callback function signature: void (api::effect_runtime *runtime) + /// + init_effect_runtime, + + /// + /// Called when an effect runtime is reset or destroyed. + /// Callback function signature: void (api::effect_runtime *runtime) + /// + destroy_effect_runtime, + + /// + /// Called after successfull sampler creation from: + /// + /// ID3D10Device::CreateSamplerState + /// ID3D11Device::CreateSamplerState + /// ID3D12Device::CreateSampler + /// vkCreateSampler + /// + /// Callback function signature: void (api::device *device, const api::sampler_desc &desc, api::sampler sampler) + /// + /// + /// Is not called in D3D9 (since samplers are loose state there) or OpenGL. + /// + init_sampler, + + /// + /// Called on sampler creation, before: + /// + /// ID3D10Device::CreateSamplerState + /// ID3D11Device::CreateSamplerState + /// ID3D12Device::CreateSampler + /// ID3D12Device::CreateRootSignature + /// vkCreateSampler + /// + /// Callback function signature: bool (api::device *device, api::sampler_desc &desc) + /// + /// + /// To overwrite the sampler description, modify desc in the callback and return , otherwise return . + /// Is not called in D3D9 (since samplers are loose state there) or OpenGL. + /// + create_sampler, + + /// + /// Called on sampler destruction, before: + /// + /// ID3D10SamplerState::Release + /// ID3D11SamplerState::Release + /// glDeleteSamplers + /// vkDestroySampler + /// + /// Callback function signature: void (api::device *device, api::sampler sampler) + /// + /// + /// Is not called in D3D9 (since samplers are loose state there), D3D12 (since samplers are descriptor handles instead of objects there) or OpenGL. + /// + destroy_sampler, + + /// + /// Called after successfull resource creation from: + /// + /// IDirect3DDevice9::CreateVertexBuffer + /// IDirect3DDevice9::CreateIndexBuffer + /// IDirect3DDevice9::CreateTexture + /// IDirect3DDevice9::CreateCubeTexture + /// IDirect3DDevice9::CreateVolumeTexture + /// IDirect3DDevice9::CreateRenderTargetSurface + /// IDirect3DDevice9::CreateDepthStencilSurface + /// IDirect3DDevice9::CreateOffscreenPlainSurface + /// IDirect3DDevice9Ex::CreateRenderTargetSurfaceEx + /// IDirect3DDevice9Ex::CreateDepthStencilSurfaceEx + /// IDirect3DDevice9Ex::CreateOffscreenPlainSurfaceEx + /// ID3D10Device::CreateBuffer + /// ID3D10Device::CreateTexture1D + /// ID3D10Device::CreateTexture2D + /// ID3D10Device::CreateTexture2D + /// ID3D11Device::CreateBuffer + /// ID3D11Device::CreateTexture1D + /// ID3D11Device::CreateTexture2D + /// ID3D11Device::CreateTexture3D + /// ID3D11Device3::CreateTexture2D + /// ID3D11Device3::CreateTexture3D + /// ID3D12Device::CreateCommittedResource + /// ID3D12Device::CreatePlacedResource + /// ID3D12Device::CreateReservedResource + /// ID3D12Device4::CreateCommittedResource1 + /// ID3D12Device4::CreateReservedResource1 + /// glBufferData + /// glBufferStorage + /// glNamedBufferData + /// glNamedBufferStorage + /// glTexImage1D + /// glTexImage2D + /// glTexImage2DMultisample + /// glTexImage3D + /// glTexImage3DMultisample + /// glCompressedTexImage1D + /// glCompressedTexImage2D + /// glCompressedTexImage3D + /// glTexStorage1D + /// glTexStorage2D + /// glTexStorage2DMultisample + /// glTexStorage3D + /// glTexStorage3DMultisample + /// glTextureStorage1D + /// glTextureStorage2D + /// glTextureStorage2DMultisample + /// glTextureStorage3D + /// glTextureStorage3DMultisample + /// glRenderbufferStorage + /// glRenderbufferStorageMultisample + /// glNamedRenderbufferStorage + /// glNamedRenderbufferStorageMultisample + /// vkBindBufferMemory + /// vkBindBufferMemory2 + /// vkBindImageMemory + /// vkBindImageMemory2 + /// + /// Callback function signature: void (api::device *device, const api::resource_desc &desc, const api::subresource_data *initial_data, api::resource_usage initial_state, api::resource resource) + /// + init_resource, + + /// + /// Called on resource creation, before: + /// + /// IDirect3DDevice9::CreateVertexBuffer + /// IDirect3DDevice9::CreateIndexBuffer + /// IDirect3DDevice9::CreateTexture + /// IDirect3DDevice9::CreateCubeTexture + /// IDirect3DDevice9::CreateVolumeTexture + /// IDirect3DDevice9::CreateRenderTargetSurface + /// IDirect3DDevice9::CreateDepthStencilSurface + /// IDirect3DDevice9::CreateOffscreenPlainSurface + /// IDirect3DDevice9Ex::CreateRenderTargetSurfaceEx + /// IDirect3DDevice9Ex::CreateDepthStencilSurfaceEx + /// IDirect3DDevice9Ex::CreateOffscreenPlainSurfaceEx + /// ID3D10Device::CreateBuffer + /// ID3D10Device::CreateTexture1D + /// ID3D10Device::CreateTexture2D + /// ID3D10Device::CreateTexture2D + /// ID3D11Device::CreateBuffer + /// ID3D11Device::CreateTexture1D + /// ID3D11Device::CreateTexture2D + /// ID3D11Device::CreateTexture3D + /// ID3D11Device3::CreateTexture2D + /// ID3D11Device3::CreateTexture3D + /// ID3D12Device::CreateCommittedResource + /// ID3D12Device::CreatePlacedResource + /// ID3D12Device::CreateReservedResource + /// ID3D12Device4::CreateCommittedResource1 + /// ID3D12Device4::CreateReservedResource1 + /// glBufferData + /// glBufferStorage + /// glNamedBufferData + /// glNamedBufferStorage + /// glTexImage1D + /// glTexImage2D + /// glTexImage2DMultisample + /// glTexImage3D + /// glTexImage3DMultisample + /// glCompressedTexImage1D + /// glCompressedTexImage2D + /// glCompressedTexImage3D + /// glTexStorage1D + /// glTexStorage2D + /// glTexStorage2DMultisample + /// glTexStorage3D + /// glTexStorage3DMultisample + /// glTextureStorage1D + /// glTextureStorage2D + /// glTextureStorage2DMultisample + /// glTextureStorage3D + /// glTextureStorage3DMultisample + /// glRenderbufferStorage + /// glRenderbufferStorageMultisample + /// glNamedRenderbufferStorage + /// glNamedRenderbufferStorageMultisample + /// vkCreateBuffer + /// vkCreateImage + /// + /// Callback function signature: bool (api::device *device, api::resource_desc &desc, api::subresource_data *initial_data, api::resource_usage initial_state) + /// + /// + /// To overwrite the resource description, modify desc in the callback and return , otherwise return . + /// + create_resource, + + /// + /// Called on resource destruction, before: + /// + /// IDirect3DResource9::Release + /// ID3D10Resource::Release + /// ID3D11Resource::Release + /// ID3D12Resource::Release + /// glDeleteBuffers + /// glDeleteTextures + /// glDeleteRenderbuffers + /// vkDestroyBuffer + /// vkDestroyImage + /// + /// Callback function signature: void (api::device *device, api::resource resource) + /// + destroy_resource, + + /// + /// Called after successfull resource view creation from: + /// + /// IDirect3DDevice9::CreateTexture + /// IDirect3DDevice9::CreateCubeTexture + /// IDirect3DDevice9::CreateVolumeTexture + /// ID3D10Device::CreateShaderResourceView + /// ID3D10Device::CreateRenderTargetView + /// ID3D10Device::CreateDepthStencilView + /// ID3D10Device1::CreateShaderResourceView1 + /// ID3D11Device::CreateShaderResourceView + /// ID3D11Device::CreateUnorderedAccessView + /// ID3D11Device::CreateRenderTargetView + /// ID3D11Device::CreateDepthStencilView + /// ID3D11Device3::CreateShaderResourceView1 + /// ID3D11Device3::CreateUnorderedAccessView1 + /// ID3D11Device3::CreateRenderTargetView1 + /// ID3D12Device::CreateShaderResourceView + /// ID3D12Device::CreateUnorderedAccessView + /// ID3D12Device::CreateRenderTargetView + /// ID3D12Device::CreateDepthStencilView + /// glTexBuffer + /// glTextureBuffer + /// glTextureView + /// vkCreateBufferView + /// vkCreateImageView + /// + /// Callback function signature: void (api::device *device, api::resource resource, api::resource_usage usage_type, const api::resource_view_desc &desc, api::resource_view view) + /// + init_resource_view, + + /// + /// Called on resource view creation, before: + /// + /// ID3D10Device::CreateShaderResourceView + /// ID3D10Device::CreateRenderTargetView + /// ID3D10Device::CreateDepthStencilView + /// ID3D10Device1::CreateShaderResourceView1 + /// ID3D11Device::CreateShaderResourceView + /// ID3D11Device::CreateUnorderedAccessView + /// ID3D11Device::CreateRenderTargetView + /// ID3D11Device::CreateDepthStencilView + /// ID3D11Device3::CreateShaderResourceView1 + /// ID3D11Device3::CreateUnorderedAccessView1 + /// ID3D11Device3::CreateRenderTargetView1 + /// ID3D12Device::CreateShaderResourceView + /// ID3D12Device::CreateUnorderedAccessView + /// ID3D12Device::CreateRenderTargetView + /// ID3D12Device::CreateDepthStencilView + /// glTexBuffer + /// glTextureBuffer + /// glTextureView + /// vkCreateBufferView + /// vkCreateImageView + /// + /// Callback function signature: bool (api::device *device, api::resource resource, api::resource_usage usage_type, api::resource_view_desc &desc) + /// + /// + /// To overwrite the resource view description, modify desc in the callback and return , otherwise return . + /// Is not called in D3D9 (since resource views are tied to resources there). + /// + create_resource_view, + + /// + /// Called on resource view destruction, before: + /// + /// IDirect3DResource9::Release + /// ID3D10View::Release + /// ID3D11View::Release + /// glDeleteTextures + /// vkDestroyBufferView + /// vkDestroyImageView + /// + /// Callback function signature: void (api::device *device, api::resource_view view) + /// + /// + /// Is not called in D3D12 (since resource views are descriptor handles instead of objects there). + /// + destroy_resource_view, + + /// + /// Called after: + /// + /// IDirect3DVertexBuffer9::Lock + /// IDirect3DIndexBuffer9::Lock + /// ID3D10Resource::Map + /// ID3D11DeviceContext::Map + /// ID3D12Resource::Map + /// glMapBuffer + /// glMapBufferRange + /// glMapNamedBuffer + /// glMapNamedBufferRange + /// + /// Callback function signature: void (api::device *device, api::resource resource, uint64_t offset, uint64_t size, api::map_access access, void **data) + /// + map_buffer_region, + + /// + /// Called before: + /// + /// IDirect3DVertexBuffer9::Unlock + /// IDirect3DIndexBuffer9::Unlock + /// ID3D10Resource::Unmap + /// ID3D11DeviceContext::Unmap + /// ID3D12Resource::Unmap + /// glUnmapBuffer + /// glUnmapNamedBuffer + /// + /// Callback function signature: void (api::device *device, api::resource resource) + /// + unmap_buffer_region, + + /// + /// Called after: + /// + /// IDirect3DSurface9::LockRect + /// IDirect3DVolume9::LockBox + /// IDirect3DTexture9::LockRect + /// IDirect3DVolumeTexture9::LockBox + /// IDirect3DCubeTexture9::LockRect + /// ID3D10Resource::Map + /// ID3D11DeviceContext::Map + /// ID3D12Resource::Map + /// + /// Callback function signature: void (api::device *device, api::resource resource, uint32_t subresource, const api::subresource_box *box, api::map_access access, api::subresource_data *data) + /// + map_texture_region, + + /// + /// Called before: + /// + /// IDirect3DSurface9::UnlockRect + /// IDirect3DVolume9::UnlockBox + /// IDirect3DTexture9::UnlockRect + /// IDirect3DVolumeTexture9::UnlockBox + /// IDirect3DCubeTexture9::UnlockRect + /// ID3D10Resource::Unmap + /// ID3D11DeviceContext::Unmap + /// ID3D12Resource::Unmap + /// + /// Callback function signature: void (api::device *device, api::resource resource, uint32_t subresource) + /// + unmap_texture_region, + + /// + /// Called before: + /// + /// ID3D10Device::UpdateSubresource + /// ID3D11DeviceContext::UpdateSubresource + /// glBufferSubData + /// glNamedBufferSubData + /// + /// Callback function signature: bool (api::device *device, const void *data, api::resource resource, uint64_t offset, uint64_t size) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Destination resource will be in the state. + /// + update_buffer_region, + + /// + /// Called before: + /// + /// ID3D10Device::UpdateSubresource + /// ID3D11DeviceContext::UpdateSubresource + /// glTexSubData1D + /// glTexSubData2D + /// glTexSubData3D + /// glTextureSubData1D + /// glTextureSubData2D + /// glTextureSubData3D + /// glCompressedTexSubData1D + /// glCompressedTexSubData2D + /// glCompressedTexSubData3D + /// glCompressedTextureSubData1D + /// glCompressedTextureSubData2D + /// glCompressedTextureSubData3D + /// + /// Callback function signature: bool (api::device *device, const api::subresource_data &data, api::resource resource, uint32_t subresource, const api::subresource_box *box) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Destination resource will be in the state. + /// + update_texture_region, + + /// + /// Called after successfull pipeline creation from: + /// + /// IDirect3DDevice9::CreateVertexShader + /// IDirect3DDevice9::CreatePixelShader + /// IDirect3DDevice9::CreateVertexDeclaration + /// ID3D10Device::CreateVertexShader + /// ID3D10Device::CreateGeometryShader + /// ID3D10Device::CreateGeometryShaderWithStreamOutput + /// ID3D10Device::CreatePixelShader + /// ID3D10Device::CreateInputLayout + /// ID3D10Device::CreateBlendState + /// ID3D10Device::CreateDepthStencilState + /// ID3D10Device::CreateRasterizerState + /// ID3D10Device1::CreateBlendState1 + /// ID3D11Device::CreateVertexShader + /// ID3D11Device::CreateHullShader + /// ID3D11Device::CreateDomainShader + /// ID3D11Device::CreateGeometryShader + /// ID3D11Device::CreateGeometryShaderWithStreamOutput + /// ID3D11Device::CreatePixelShader + /// ID3D11Device::CreateComputeShader + /// ID3D11Device::CreateInputLayout + /// ID3D11Device::CreateBlendState + /// ID3D11Device::CreateDepthStencilState + /// ID3D11Device::CreateRasterizerState + /// ID3D11Device1::CreateBlendState1 + /// ID3D11Device1::CreateRasterizerState1 + /// ID3D11Device3::CreateRasterizerState2 + /// ID3D12Device::CreateComputePipelineState + /// ID3D12Device::CreateGraphicsPipelineState + /// ID3D12Device2::CreatePipelineState + /// ID3D12PipelineLibrary::LoadComputePipeline + /// ID3D12PipelineLibrary::LoadGraphicsPipeline + /// ID3D12PipelineLibrary1::LoadPipeline + /// glLinkProgram + /// vkCreateComputePipelines + /// vkCreateGraphicsPipelines + /// + /// Callback function signature: void (api::device *device, api::pipeline_layout layout, uint32_t subobject_count, const api::pipeline_subobject *subobjects, api::pipeline pipeline) + /// + /// + /// May be called multiple times with the same pipeline handle (whenever the pipeline is updated or its reference count is incremented). + /// + init_pipeline, + + /// + /// Called on pipeline creation, before: + /// + /// IDirect3DDevice9::CreateVertexShader + /// IDirect3DDevice9::CreatePixelShader + /// IDirect3DDevice9::CreateVertexDeclaration + /// ID3D10Device::CreateVertexShader + /// ID3D10Device::CreateGeometryShader + /// ID3D10Device::CreateGeometryShaderWithStreamOutput + /// ID3D10Device::CreatePixelShader + /// ID3D10Device::CreateInputLayout + /// ID3D10Device::CreateBlendState + /// ID3D10Device::CreateDepthStencilState + /// ID3D10Device::CreateRasterizerState + /// ID3D10Device1::CreateBlendState1 + /// ID3D11Device::CreateVertexShader + /// ID3D11Device::CreateHullShader + /// ID3D11Device::CreateDomainShader + /// ID3D11Device::CreateGeometryShader + /// ID3D11Device::CreateGeometryShaderWithStreamOutput + /// ID3D11Device::CreatePixelShader + /// ID3D11Device::CreateComputeShader + /// ID3D11Device::CreateInputLayout + /// ID3D11Device::CreateBlendState + /// ID3D11Device::CreateDepthStencilState + /// ID3D11Device::CreateRasterizerState + /// ID3D11Device1::CreateBlendState1 + /// ID3D11Device1::CreateRasterizerState1 + /// ID3D11Device3::CreateRasterizerState2 + /// ID3D12Device::CreateComputePipelineState + /// ID3D12Device::CreateGraphicsPipelineState + /// ID3D12Device2::CreatePipelineState + /// glShaderSource + /// vkCreateComputePipelines + /// vkCreateGraphicsPipelines + /// + /// Callback function signature: bool (api::device *device, api::pipeline_layout layout, uint32_t subobject_count, const api::pipeline_subobject *subobjects) + /// + /// + /// To overwrite the pipeline description, modify desc in the callback and return , otherwise return . + /// + create_pipeline, + + /// + /// Called on pipeline destruction, before: + /// + /// ID3D10VertexShader::Release + /// ID3D10GeometryShader::Release + /// ID3D10PixelShader::Release + /// ID3D10InputLayout::Release + /// ID3D10BlendState::Release + /// ID3D10DepthStencilState::Release + /// ID3D10RasterizerState::Release + /// ID3D11VertexShader::Release + /// ID3D11HullShader::Release + /// ID3D11DomainShader::Release + /// ID3D11GeometryShader::Release + /// ID3D11PixelShader::Release + /// ID3D11ComputeShader::Release + /// ID3D11InputLayout::Release + /// ID3D11BlendState::Release + /// ID3D11DepthStencilState::Release + /// ID3D11RasterizerState::Release + /// ID3D12PipelineState::Release + /// glDeleteProgram + /// vkDestroyPipeline + /// + /// Callback function signature: void (api::device *device, api::pipeline pipeline) + /// + /// + /// Is not called in D3D9. + /// + destroy_pipeline, + + /// + /// Called after successfull pipeline layout creation from: + /// + /// ID3D12Device::CreateRootSignature + /// vkCreatePipelineLayout + /// + /// Callback function signature: void (api::device *device, uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout layout) + /// + init_pipeline_layout, + + /// + /// Called on pipeline layout creation. + /// Callback function signature: bool (api::device *device, uint32_t param_count, const api::pipeline_layout_param *params) + /// + create_pipeline_layout, + + /// + /// Called on pipeline layout destruction, before: + /// + /// ID3D12RootSignature::Release + /// VkDestroyPipelineLayout + /// + /// Callback function signature: void (api::device *device, api::pipeline_layout layout) + /// + destroy_pipeline_layout, + + /// + /// Called before: + /// + /// ID3D12Device::CopyDescriptors + /// ID3D12Device::CopyDescriptorsSimple + /// vkUpdateDescriptorSets + /// + /// Callback function signature: bool (api::device *device, uint32_t count, const api::descriptor_table_copy *copies) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + copy_descriptor_tables, + + /// + /// Called before: + /// + /// ID3D12Device::CreateConstantBufferView + /// ID3D12Device::CreateShaderResourceView + /// ID3D12Device::CreateUnorderedAccessView + /// ID3D12Device::CreateSampler + /// vkUpdateDescriptorSets + /// + /// Callback function signature: bool (api::device *device, uint32_t count, const api::descriptor_table_update *updates) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + update_descriptor_tables, + + /// + /// Called after successfull query heap creation from: + /// + /// ID3D12Device::CreateQueryHeap + /// vkCreateQueryPool + /// + /// Callback function signature: void (api::device *device, api::query_type type, uint32_t size, api::query_heap heap) + /// + init_query_heap, + + /// + /// Called on query heap creation, before: + /// + /// ID3D12Device::CreateQueryHeap + /// vkCreateQueryPool + /// + /// Callback function signature: bool (api::device *device, api::query_type type, uint32_t &size) + /// + create_query_heap, + + /// + /// Called on query heap destruction, before: + /// + /// ID3D12QueryHeap::Release + /// vkDestroyQueryPool + /// + /// Callback function signature: void (api::device *device, api::query_heap heap) + /// + destroy_query_heap, + + /// + /// Called before: + /// + /// vkGetQueryPoolResults + /// + /// Callback function signature: bool (api::device *device, api::query_heap heap, uint32_t first, uint32_t count, void *results, uint32_t stride) + /// + get_query_heap_results, + + /// + /// Called after: + /// + /// ID3D12GraphicsCommandList::ResourceBarrier + /// ID3D12GraphicsCommandList7::Barrier + /// vkCmdPipelineBarrier + /// vkCmdPipelineBarrier2 + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t count, const api::resource *resources, const api::resource_usage *old_states, const api::resource_usage *new_states) + /// + barrier, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList4::BeginRenderPass + /// vkCmdBeginRenderPass + /// vkCmdBeginRenderPass2 + /// vkCmdNextSubpass + /// vkCmdNextSubpass2 + /// vkCmdBeginRendering + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t count, const api::render_pass_render_target_desc *rts, const api::render_pass_depth_stencil_desc *ds) + /// + /// + /// The depth-stencil description argument is optional and may be . + /// + begin_render_pass, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList4::EndRenderPass + /// vkCmdEndRenderPass + /// vkCmdEndRenderPass2 + /// vkCmdNextSubpass + /// vkCmdNextSubpass2 + /// vkCmdEndRendering + /// + /// Callback function signature: void (api::command_list *cmd_list) + /// + end_render_pass, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetRenderTarget + /// IDirect3DDevice9::SetDepthStencilSurface + /// ID3D10Device::OMSetRenderTargets + /// ID3D11DeviceContext::OMSetRenderTargets + /// ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews + /// ID3D12GraphicsCommandList::OMSetRenderTargets + /// glBindFramebuffer + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t count, const api::resource_view *rtvs, api::resource_view dsv) + /// + bind_render_targets_and_depth_stencil, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetVertexShader + /// IDirect3DDevice9::SetPixelShader + /// IDirect3DDevice9::SetVertexDeclaration + /// IDirect3DDevice9::ProcessVertices + /// ID3D10Device::VSSetShader + /// ID3D10Device::GSSetShader + /// ID3D10Device::PSSetShader + /// ID3D10Device::IASetInputLayout + /// ID3D10Device::OMSetBlendState + /// ID3D10Device::OMSetDepthStencilState + /// ID3D10Device::RSSetState + /// ID3D11DeviceContext::VSSetShader + /// ID3D11DeviceContext::HSSetShader + /// ID3D11DeviceContext::DSSetShader + /// ID3D11DeviceContext::GSSetShader + /// ID3D11DeviceContext::PSSetShader + /// ID3D11DeviceContext::CSSetShader + /// ID3D11DeviceContext::IASetInputLayout + /// ID3D11DeviceContext::OMSetBlendState + /// ID3D11DeviceContext::OMSetDepthStencilState + /// ID3D11DeviceContext::RSSetState + /// ID3D12GraphicsCommandList::Reset + /// ID3D12GraphicsCommandList::SetPipelineState + /// glUseProgram + /// vkCmdBindPipeline + /// + /// Callback function signature: void (api::command_list *cmd_list, api::pipeline_stage stages, api::pipeline pipeline) + /// + bind_pipeline, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetRenderState + /// ID3D10Device::IASetPrimitiveTopology + /// ID3D10Device::OMSetBlendState + /// ID3D10Device::OMSetDepthStencilState + /// ID3D11DeviceContext::IASetPrimitiveTopology + /// ID3D11DeviceContext::OMSetBlendState + /// ID3D11DeviceContext::OMSetDepthStencilState + /// ID3D12GraphicsCommandList::IASetPrimitiveTopology + /// ID3D12GraphicsCommandList::OMSetBlendFactor + /// ID3D12GraphicsCommandList::OMSetStencilRef + /// gl(...) + /// vkCmdSetDepthBias + /// vkCmdSetBlendConstants + /// vkCmdSetStencilCompareMask + /// vkCmdSetStencilWriteMask + /// vkCmdSetStencilReference + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t count, const api::dynamic_state *states, const uint32_t *values) + /// + bind_pipeline_states, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetViewport + /// IDirect3DDevice9::SetRenderTarget (implicitly updates the viewport) + /// ID3D10Device::RSSetViewports + /// ID3D11DeviceContext::RSSetViewports + /// ID3D12GraphicsCommandList::RSSetViewports + /// glViewport + /// glViewportArrayv + /// glViewportIndexedf + /// glViewportIndexedfv + /// vkCmdSetViewport + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t first, uint32_t count, const api::viewport *viewports) + /// + bind_viewports, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetScissorRect + /// ID3D10Device::RSSetScissorRects + /// ID3D11DeviceContext::RSSetScissorRects + /// ID3D12GraphicsCommandList::RSSetScissorRects + /// glScissor + /// glScissorArrayv + /// glScissorIndexed + /// glScissorIndexedv + /// vkCmdSetScissor + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t first, uint32_t count, const api::rect *rects) + /// + bind_scissor_rects, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetVertexShaderConstantF + /// IDirect3DDevice9::SetPixelShaderConstantF + /// ID3D12GraphicsCommandList::SetComputeRoot32BitConstant + /// ID3D12GraphicsCommandList::SetComputeRoot32BitConstants + /// ID3D12GraphicsCommandList::SetGraphicsRoot32BitConstant + /// ID3D12GraphicsCommandList::SetGraphicsRoot32BitConstants + /// glUniform(...) + /// vkCmdPushConstants + /// + /// Callback function signature: void (api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t layout_param, uint32_t first, uint32_t count, const void *values) + /// + push_constants, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetTexture + /// ID3D10Device::VSSetSamplers + /// ID3D10Device::VSSetShaderResources + /// ID3D10Device::VSSetConstantBuffers + /// ID3D10Device::GSSetSamplers + /// ID3D10Device::GSSetShaderResources + /// ID3D10Device::GSSetConstantBuffers + /// ID3D10Device::PSSetSamplers + /// ID3D10Device::PSSetShaderResources + /// ID3D10Device::PSSetConstantBuffers + /// ID3D11DeviceContext::VSSetSamplers + /// ID3D11DeviceContext::VSSetShaderResources + /// ID3D11DeviceContext::VSSetConstantBuffers + /// ID3D11DeviceContext::HSSetSamplers + /// ID3D11DeviceContext::HSSetShaderResources + /// ID3D11DeviceContext::HSSetConstantBuffers + /// ID3D11DeviceContext::DSSetSamplers + /// ID3D11DeviceContext::DSSetShaderResources + /// ID3D11DeviceContext::DSSetConstantBuffers + /// ID3D11DeviceContext::GSSetSamplers + /// ID3D11DeviceContext::GSSetShaderResources + /// ID3D11DeviceContext::GSSetConstantBuffers + /// ID3D11DeviceContext::PSSetSamplers + /// ID3D11DeviceContext::PSSetShaderResources + /// ID3D11DeviceContext::PSSetConstantBuffers + /// ID3D11DeviceContext::CSSetSamplers + /// ID3D11DeviceContext::CSSetShaderResources + /// ID3D11DeviceContext::CSSetUnorderedAccessViews + /// ID3D11DeviceContext::CSSetConstantBuffers + /// ID3D12GraphicsCommandList::SetComputeRootConstantBufferView + /// ID3D12GraphicsCommandList::SetGraphicsRootConstantBufferView + /// ID3D12GraphicsCommandList::SetComputeRootShaderResourceView + /// ID3D12GraphicsCommandList::SetGraphicsRootShaderResourceView + /// ID3D12GraphicsCommandList::SetComputeRootUnorderedAccessView + /// ID3D12GraphicsCommandList::SetGraphicsRootUnorderedAccessView + /// glBindBufferBase + /// glBindBufferRange + /// glBindBuffersBase + /// glBindBuffersRange + /// glBindTexture + /// glBindImageTexture + /// glBindTextures + /// glBindImageTextures + /// glBindTextureUnit + /// glBindMultiTextureEXT + /// vkCmdPushDescriptorSetKHR + /// + /// Callback function signature: void (api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t layout_param, const api::descriptor_table_update &update) + /// + push_descriptors, + + /// + /// Called after: + /// + /// ID3D12GraphicsCommandList::SetComputeRootSignature + /// ID3D12GraphicsCommandList::SetGraphicsRootSignature + /// ID3D12GraphicsCommandList::SetComputeRootDescriptorTable + /// ID3D12GraphicsCommandList::SetGraphicsRootDescriptorTable + /// vkCmdBindDescriptorSets + /// + /// Callback function signature: void (api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t first, uint32_t count, const api::descriptor_table *tables) + /// + bind_descriptor_tables, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetIndices + /// ID3D10Device::IASetIndexBuffer + /// ID3D11DeviceContext::IASetIndexBuffer + /// ID3D12GraphicsCommandList::IASetIndexBuffer + /// glBindBuffer + /// vkCmdBindIndexBuffer + /// + /// Callback function signature: void (api::command_list *cmd_list, api::resource buffer, uint64_t offset, uint32_t index_size) + /// + bind_index_buffer, + + /// + /// Called after: + /// + /// IDirect3DDevice9::SetStreamSource + /// ID3D10Device::IASetVertexBuffers + /// ID3D11DeviceContext::IASetVertexBuffers + /// ID3D12GraphicsCommandList::IASetVertexBuffers + /// glBindBuffer + /// glBindVertexBuffer + /// glBindVertexBuffers + /// vkCmdBindVertexBuffers + /// vkCmdBindVertexBuffers2 + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint32_t *strides) + /// + /// + /// The strides argument is optional and may be . + /// + bind_vertex_buffers, + + /// + /// Called after: + /// + /// IDirect3DDevice9::ProcessVertices + /// ID3D10Device::SOSetTargets + /// ID3D11DeviceContext::SOSetTargets + /// ID3D12GraphicsCommandList::SOSetTargets + /// glBindBufferBase + /// glBindBufferRange + /// glBindBuffersBase + /// glBindBuffersRange + /// vkCmdBindTransformFeedbackBuffersEXT + /// + /// Callback function signature: void (api::command_list *cmd_list, uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint64_t *max_sizes, const api::resource *counter_buffers, const uint64_t *counter_offsets) + /// + /// + /// The counter arguments are optional and may be . + /// + bind_stream_output_buffers, + + /// + /// Called before: + /// + /// IDirect3DDevice9::DrawPrimitive + /// IDirect3DDevice9::DrawPrimitiveUP + /// IDirect3DDevice9::ProcessVertices + /// ID3D10Device::Draw + /// ID3D10Device::DrawInstanced + /// ID3D11DeviceContext::Draw + /// ID3D11DeviceContext::DrawInstanced + /// ID3D12GraphicsCommandList::DrawInstanced + /// glDrawArrays + /// glDrawArraysInstanced + /// glDrawArraysInstancedBaseInstance + /// glMultiDrawArrays + /// vkCmdDraw + /// + /// Callback function signature: bool (api::command_list *cmd_list, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + draw, + + /// + /// Called before: + /// + /// IDirect3DDevice9::DrawIndexedPrimitive + /// IDirect3DDevice9::DrawIndexedPrimitiveUP + /// ID3D10Device::DrawIndexed + /// ID3D10Device::DrawIndexedInstanced + /// ID3D11DeviceContext::DrawIndexed + /// ID3D11DeviceContext::DrawIndexedInstanced + /// ID3D12GraphicsCommandList::DrawIndexedInstanced + /// glDrawElements + /// glDrawElementsBaseVertex + /// glDrawElementsInstanced + /// glDrawElementsInstancedBaseVertex + /// glDrawElementsInstancedBaseInstance + /// glDrawElementsInstancedBaseVertexBaseInstance + /// glMultiDrawElements + /// glMultiDrawElementsBaseVertex + /// vkCmdDrawIndexed + /// + /// Callback function signature: bool (api::command_list *cmd_list, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset, uint32_t first_instance) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + draw_indexed, + + /// + /// Called before: + /// + /// ID3D11DeviceContext::Dispatch + /// ID3D12GraphicsCommandList::Dispatch + /// glDispatchCompute + /// vkCmdDispatch + /// + /// Callback function signature: bool (api::command_list *cmd_list, uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + dispatch, + + /// + /// Called before: + /// + /// ID3D11DeviceContext::DrawInstancedIndirect + /// ID3D11DeviceContext::DrawIndexedInstancedIndirect + /// ID3D11DeviceContext::DispatchIndirect + /// ID3D12GraphicsCommandList::ExecuteIndirect + /// glDrawArraysIndirect + /// glDrawElementsIndirect + /// glMultiDrawArraysIndirect + /// glMultiDrawElementsIndirect + /// glDispatchComputeIndirect + /// vkCmdDrawIndirect + /// vkCmdDrawIndexedIndirect + /// vkCmdDispatchIndirect + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::indirect_command type, api::resource buffer, uint64_t offset, uint32_t draw_count, uint32_t stride) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + draw_or_dispatch_indirect, + + /// + /// Called before: + /// + /// IDirect3DDevice9::UpdateTexture + /// IDirect3DDevice9::GetRenderTargetData + /// ID3D10Device::CopyResource + /// ID3D11DeviceContext::CopyResource + /// ID3D12GraphicsCommandList::CopyResource + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, api::resource dest) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// + copy_resource, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::CopyBufferRegion + /// glCopyBufferSubData + /// glCopyNamedBufferSubData + /// vkCmdCopyBuffer + /// vkCmdCopyBuffer2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, uint64_t source_offset, api::resource dest, uint64_t dest_offset, uint64_t size) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// + copy_buffer_region, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::CopyTextureRegion + /// vkCmdCopyBufferToImage + /// vkCmdCopyBufferToImage2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, uint64_t source_offset, uint32_t row_length, uint32_t slice_height, api::resource dest, uint32_t dest_subresource, const api::subresource_box *dest_box) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// The subresource box argument is optional and may be . + /// + copy_buffer_to_texture, + + /// + /// Called before: + /// + /// IDirect3DDevice9::UpdateSurface + /// IDirect3DDevice9::StretchRect + /// ID3D10Device::CopySubresourceRegion + /// ID3D11DeviceContext::CopySubresourceRegion + /// ID3D12GraphicsCommandList::CopyTextureRegion + /// glBlitFramebuffer + /// glBlitNamedFramebuffer + /// glCopyImageSubData + /// glCopyTexSubImage1D + /// glCopyTexSubImage2D + /// glCopyTexSubImage3D + /// glCopyTextureSubImage1D + /// glCopyTextureSubImage2D + /// glCopyTextureSubImage3D + /// vkCmdBlitImage + /// vkCmdBlitImage2 + /// vkCmdCopyImage + /// vkCmdCopyImage2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint32_t dest_subresource, const api::subresource_box *dest_box, api::filter_mode filter) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// The subresource box arguments are optional and may be . + /// + copy_texture_region, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::CopyTextureRegion + /// vkCmdCopyImageToBuffer + /// vkCmdCopyImageToBuffer2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint64_t dest_offset, uint32_t row_length, uint32_t slice_height) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// The subresource box argument is optional and may be . + /// + copy_texture_to_buffer, + + /// + /// Called before: + /// + /// IDirect3DDevice9::StretchRect + /// ID3D10Device::ResolveSubresource + /// ID3D11DeviceContext::ResolveSubresource + /// ID3D12GraphicsCommandList::ResolveSubresource + /// ID3D12GraphicsCommandList1::ResolveSubresourceRegion + /// glBlitFramebuffer + /// glBlitNamedFramebuffer + /// vkCmdResolveImage + /// vkCmdResolveImage2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint32_t dest_subresource, int32_t dest_x, int32_t dest_y, int32_t dest_z, api::format format) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Source resource will be in the state. + /// Destination resource will be in the state. + /// The subresource box argument is optional and may be . + /// + resolve_texture_region, + + /// + /// Called before: + /// + /// IDirect3DDevice9::Clear + /// ID3D10Device::ClearDepthStencilView + /// ID3D11DeviceContext::ClearDepthStencilView + /// ID3D11DeviceContext1::ClearView (for depth-stencil views) + /// ID3D12GraphicsCommandList::ClearDepthStencilView + /// glClear + /// glClearBufferfi + /// glClearBufferfv + /// glClearNamedFramebufferfi + /// glClearNamedFramebufferfv + /// vkCmdClearDepthStencilImage + /// vkCmdClearAttachments + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource_view dsv, const float *depth, const uint8_t *stencil, uint32_t rect_count, const api::rect *rects) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Resource will be in the state. + /// One of the depth or stencil clear value arguments may be when the respective component is not cleared. + /// + clear_depth_stencil_view, + + /// + /// Called before: + /// + /// IDirect3DDevice9::Clear + /// IDirect3DDevice9::ColorFill + /// ID3D10Device::ClearRenderTargetView + /// ID3D11DeviceContext::ClearRenderTargetView + /// ID3D11DeviceContext1::ClearView (for render target views) + /// ID3D12GraphicsCommandList::ClearRenderTargetView + /// glClear + /// glClearBufferfv + /// glClearNamedFramebufferfv + /// vkCmdClearColorImage + /// vkCmdClearAttachments + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource_view rtv, const float color[4], uint32_t rect_count, const api::rect *rects) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Resources will be in the state. + /// + clear_render_target_view, + + /// + /// Called before: + /// + /// ID3D11DeviceContext::ClearUnorderedAccessViewUint + /// ID3D12GraphicsCommandList::ClearUnorderedAccessViewUint + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource_view uav, const uint32_t values[4], uint32_t rect_count, const api::rect *rects) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Resource will be in the state. + /// + clear_unordered_access_view_uint, + + /// + /// Called before: + /// + /// ID3D11DeviceContext::ClearUnorderedAccessViewFloat + /// ID3D11DeviceContext1::ClearView (for unordered access views) + /// ID3D12GraphicsCommandList::ClearUnorderedAccessViewFloat + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource_view uav, const float values[4], uint32_t rect_count, const api::rect *rects) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// Resource will be in the state. + /// + clear_unordered_access_view_float, + + /// + /// Called before: + /// + /// ID3D10Device::GenerateMips + /// ID3D11DeviceContext::GenerateMips + /// glGenerateMipmap + /// glGenerateTextureMipmap + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::resource_view srv) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + generate_mipmaps, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::BeginQuery + /// vkCmdBeginQuery + /// vkCmdBeginQueryIndexedEXT + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t index) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + begin_query, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::EndQuery + /// vkCmdEndQuery + /// vkCmdEndQueryIndexedEXT + /// vkCmdWriteTimestamp + /// vkCmdWriteTimestamp2 + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t index) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + end_query, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::ResolveQueryData + /// vkCmdCopyQueryPoolResults + /// + /// Callback function signature: bool (api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t first, uint32_t count, api::resource dest, uint64_t dest_offset, uint32_t stride) + /// + /// + /// To prevent this command from being executed, return , otherwise return . + /// + copy_query_heap_results, + + /// + /// Called before: + /// + /// ID3D12GraphicsCommandList::Reset + /// vkBeginCommandBuffer + /// + /// Callback function signature: void (api::command_list *cmd_list) + /// + /// + /// Is not called for immediate command lists (since they cannot be reset). + /// + reset_command_list, + + /// + /// Called before: + /// + /// ID3D11DeviceContext::FinishCommandList + /// ID3D12GraphicsCommandList::Close + /// vkEndCommandBuffer + /// + /// Callback function signature: void (api::command_list *cmd_list) + /// + /// + /// Is not called for immediate command lists (since they cannot be closed). + /// + close_command_list, + + /// + /// Called when a command list is submitted to a command queue (or an immediate command list is flushed), before: + /// + /// IDirect3DDevice9::EndScene + /// ID3D10Device::Flush + /// ID3D11DeviceContext::Flush + /// ID3D11DeviceContext3::Flush1 + /// ID3D12CommandQueue::ExecuteCommandLists + /// glFlush + /// vkQueueSubmit + /// + /// Callback function signature: void (api::command_queue *queue, api::command_list *cmd_list) + /// + execute_command_list, + + /// + /// Called when a secondary command list is executed on a primary command list, before: + /// + /// ID3D11DeviceContext::ExecuteCommandList + /// ID3D12GraphicsCommandList::ExecuteBundle + /// vkCmdExecuteCommands + /// + /// In addition, called after: + /// + /// ID3D11DeviceContext::FinishCommandList + /// + /// Callback function signature: void (api::command_list *cmd_list, api::command_list *secondary_cmd_list) + /// + execute_secondary_command_list, + + /// + /// Called before: + /// + /// IDirect3DDevice9::Present + /// IDirect3DDevice9Ex::PresentEx + /// IDirect3DSwapChain9::Present + /// IDXGISwapChain::Present + /// IDXGISwapChain3::Present1 + /// ID3D12CommandQueueDownlevel::Present + /// wglSwapBuffers + /// vkQueuePresentKHR + /// IVRCompositor::Submit + /// + /// Callback function signature: void (api::command_queue *queue, api::swapchain *swapchain, const api::rect *source_rect, const api::rect *dest_rect, uint32_t dirty_rect_count, const api::rect *dirty_rects) + /// + /// + /// The source and destination rectangle arguments are optional and may be . + /// + present, + + /// + /// Called after ReShade has rendered its overlay. + /// Callback function signature: void (api::effect_runtime *runtime) + /// + reshade_present, + + /// + /// Called right before ReShade effects are rendered. + /// Callback function signature: void (api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb) + /// + reshade_begin_effects, + + /// + /// Called right after ReShade effects were rendered. + /// Callback function signature: void (api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb) + /// + reshade_finish_effects, + + /// + /// Called right after all ReShade effects were reloaded. + /// This occurs during effect runtime initialization or because the user pressed the "Reload" button in the overlay. + /// Callback function signature: void (api::effect_runtime *runtime) + /// + reshade_reloaded_effects, + + /// + /// Called before a uniform variable is changed. + /// Callback function signature: bool (api::effect_runtime *runtime, api::effect_uniform_variable variable, const void *data, size_t size) + /// + /// + /// To prevent the variable from being changed, return , otherwise return . + /// + reshade_set_uniform_value, + /// + /// Called before a technique is enabled or disabled. + /// Callback function signature: bool (api::effect_runtime *runtime, api::effect_technique technique, bool enabled) + /// + /// + /// To prevent the technique from being changed, return , otherwise return . + /// + reshade_set_technique_state, + + /// + /// Called between the ImGui::NewFrame and ImGui::EndFrame calls for the ReShade overlay. + /// Can be used to perform custom Dear ImGui calls, but it is recommended to instead use to register a dedicated overlay. + /// Callback function signature: void (api::effect_runtime *runtime) + /// + /// + /// This is not called for effect runtimes in VR. + /// + reshade_overlay, + + /// + /// Called after a screenshot was taken and saved to disk. + /// Callback function signature: void (api::effect_runtime *runtime, const char *path) + /// + reshade_screenshot, + + /// + /// Called for each technique after it was rendered, usually between and . + /// Callback function signature: void (api::effect_runtime *runtime, api::effect_technique technique, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb) + /// + reshade_render_technique, + + /// + /// Called after a preset was loaded and applied. + /// This occurs during reloading or when the user chooses a new preset in the overlay. + /// Callback function signature: void (api::effect_runtime *runtime, const char *path) + /// + reshade_set_current_preset_path, + + /// + /// Called when the rendering order of loaded techniques is changed. + /// Callback function signature: bool (api::effect_runtime *runtime, size_t count, api::effect_technique *techniques) + /// + /// + /// To prevent the order from being changed, return , otherwise return . + /// + reshade_reorder_techniques, + +#if RESHADE_ADDON + max // Last value used internally by ReShade to determine number of events in this enum +#endif + }; + + template + struct addon_event_traits; + +#define RESHADE_DEFINE_ADDON_EVENT_TRAITS(ev, ret, ...) \ + template <> \ + struct addon_event_traits { \ + using decl = ret(*)(__VA_ARGS__); \ + using type = ret; \ + } + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_device, void, api::device *device); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_device, void, api::device *device); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_command_list, void, api::command_list *cmd_list); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_command_list, void, api::command_list *cmd_list); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_command_queue, void, api::command_queue *queue); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_command_queue, void, api::command_queue *queue); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_swapchain, void, api::swapchain *swapchain); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_swapchain, bool, api::swapchain_desc &desc, void *hwnd); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_swapchain, void, api::swapchain *swapchain); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_effect_runtime, void, api::effect_runtime *runtime); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_effect_runtime, void, api::effect_runtime *runtime); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_sampler, void, api::device *device, const api::sampler_desc &desc, api::sampler sampler); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_sampler, bool, api::device *device, api::sampler_desc &desc); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_sampler, void, api::device *device, api::sampler sampler); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_resource, void, api::device *device, const api::resource_desc &desc, const api::subresource_data *initial_data, api::resource_usage initial_state, api::resource resource); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_resource, bool, api::device *device, api::resource_desc &desc, api::subresource_data *initial_data, api::resource_usage initial_state); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_resource, void, api::device *device, api::resource resource); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_resource_view, void, api::device *device, api::resource resource, api::resource_usage usage_type, const api::resource_view_desc &desc, api::resource_view view); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_resource_view, bool, api::device *device, api::resource resource, api::resource_usage usage_type, api::resource_view_desc &desc); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_resource_view, void, api::device *device, api::resource_view view); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::map_buffer_region, void, api::device *device, api::resource resource, uint64_t offset, uint64_t size, api::map_access access, void **data); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::unmap_buffer_region, void, api::device *device, api::resource resource); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::map_texture_region, void, api::device *device, api::resource resource, uint32_t subresource, const api::subresource_box *box, api::map_access access, api::subresource_data *data); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::unmap_texture_region, void, api::device *device, api::resource resource, uint32_t subresource); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::update_buffer_region, bool, api::device *device, const void *data, api::resource resource, uint64_t offset, uint64_t size); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::update_texture_region, bool, api::device *device, const api::subresource_data &data, api::resource resource, uint32_t subresource, const api::subresource_box *box); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_pipeline, void, api::device *device, api::pipeline_layout layout, uint32_t subobject_count, const api::pipeline_subobject *subobjects, api::pipeline pipeline); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_pipeline, bool, api::device *device, api::pipeline_layout layout, uint32_t subobject_count, const api::pipeline_subobject *subobjects); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_pipeline, void, api::device *device, api::pipeline pipeline); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_pipeline_layout, void, api::device *device, uint32_t param_count, const api::pipeline_layout_param *params, api::pipeline_layout layout); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_pipeline_layout, bool, api::device *device, uint32_t param_count, const api::pipeline_layout_param *params); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_pipeline_layout, void, api::device *device, api::pipeline_layout layout); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_descriptor_tables, bool, api::device *device, uint32_t count, const api::descriptor_table_copy *copies); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::update_descriptor_tables, bool, api::device *device, uint32_t count, const api::descriptor_table_update *updates); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::init_query_heap, void, api::device *device, api::query_type type, uint32_t size, api::query_heap heap); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::create_query_heap, bool, api::device *device, api::query_type type, uint32_t &size); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::destroy_query_heap, void, api::device *device, api::query_heap heap); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::get_query_heap_results, bool, api::device *device, api::query_heap heap, uint32_t first, uint32_t count, void *results, uint32_t stride); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::barrier, void, api::command_list *cmd_list, uint32_t count, const api::resource *resources, const api::resource_usage *old_states, const api::resource_usage *new_states); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::begin_render_pass, void, api::command_list *cmd_list, uint32_t count, const api::render_pass_render_target_desc *rts, const api::render_pass_depth_stencil_desc *ds); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::end_render_pass, void, api::command_list *cmd_list); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_render_targets_and_depth_stencil, void, api::command_list *cmd_list, uint32_t count, const api::resource_view *rtvs, api::resource_view dsv); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_pipeline, void, api::command_list *cmd_list, api::pipeline_stage stages, api::pipeline pipeline); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_pipeline_states, void, api::command_list *cmd_list, uint32_t count, const api::dynamic_state *states, const uint32_t *values); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_viewports, void, api::command_list *cmd_list, uint32_t first, uint32_t count, const api::viewport *viewports); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_scissor_rects, void, api::command_list *cmd_list, uint32_t first, uint32_t count, const api::rect *rects); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::push_constants, void, api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t layout_param, uint32_t first, uint32_t count, const void *values); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::push_descriptors, void, api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t layout_param, const api::descriptor_table_update &update); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_descriptor_tables, void, api::command_list *cmd_list, api::shader_stage stages, api::pipeline_layout layout, uint32_t first, uint32_t count, const api::descriptor_table *tables); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_index_buffer, void, api::command_list *cmd_list, api::resource buffer, uint64_t offset, uint32_t index_size); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_vertex_buffers, void, api::command_list *cmd_list, uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint32_t *strides); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::bind_stream_output_buffers, void, api::command_list *cmd_list, uint32_t first, uint32_t count, const api::resource *buffers, const uint64_t *offsets, const uint64_t *max_sizes, const api::resource *counter_buffers, const uint64_t *counter_offsets); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::draw, bool, api::command_list *cmd_list, uint32_t vertex_count, uint32_t instance_count, uint32_t first_vertex, uint32_t first_instance); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::draw_indexed, bool, api::command_list *cmd_list, uint32_t index_count, uint32_t instance_count, uint32_t first_index, int32_t vertex_offset, uint32_t first_instance); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::dispatch, bool, api::command_list *cmd_list, uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::draw_or_dispatch_indirect, bool, api::command_list *cmd_list, api::indirect_command type, api::resource buffer, uint64_t offset, uint32_t draw_count, uint32_t stride); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_resource, bool, api::command_list *cmd_list, api::resource source, api::resource dest); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_buffer_region, bool, api::command_list *cmd_list, api::resource source, uint64_t source_offset, api::resource dest, uint64_t dest_offset, uint64_t size); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_buffer_to_texture, bool, api::command_list *cmd_list, api::resource source, uint64_t source_offset, uint32_t row_length, uint32_t slice_height, api::resource dest, uint32_t dest_subresource, const api::subresource_box *dest_box); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_texture_region, bool, api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint32_t dest_subresource, const api::subresource_box *dest_box, api::filter_mode filter); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_texture_to_buffer, bool, api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint64_t dest_offset, uint32_t row_length, uint32_t slice_height); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::resolve_texture_region, bool, api::command_list *cmd_list, api::resource source, uint32_t source_subresource, const api::subresource_box *source_box, api::resource dest, uint32_t dest_subresource, int32_t dest_x, int32_t dest_y, int32_t dest_z, api::format format); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::clear_depth_stencil_view, bool, api::command_list *cmd_list, api::resource_view dsv, const float *depth, const uint8_t *stencil, uint32_t rect_count, const api::rect *rects); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::clear_render_target_view, bool, api::command_list *cmd_list, api::resource_view rtv, const float color[4], uint32_t rect_count, const api::rect *rects); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::clear_unordered_access_view_uint, bool, api::command_list *cmd_list, api::resource_view uav, const uint32_t values[4], uint32_t rect_count, const api::rect *rects); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::clear_unordered_access_view_float, bool, api::command_list *cmd_list, api::resource_view uav, const float values[4], uint32_t rect_count, const api::rect *rects); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::generate_mipmaps, bool, api::command_list *cmd_list, api::resource_view srv); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::begin_query, bool, api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t index); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::end_query, bool, api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t index); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::copy_query_heap_results, bool, api::command_list *cmd_list, api::query_heap heap, api::query_type type, uint32_t first, uint32_t count, api::resource dest, uint64_t dest_offset, uint32_t stride); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reset_command_list, void, api::command_list *cmd_list); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::close_command_list, void, api::command_list *cmd_list); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::execute_command_list, void, api::command_queue *queue, api::command_list *cmd_list); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::execute_secondary_command_list, void, api::command_list *cmd_list, api::command_list *secondary_cmd_list); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::present, void, api::command_queue *queue, api::swapchain *swapchain, const api::rect *source_rect, const api::rect *dest_rect, uint32_t dirty_rect_count, const api::rect *dirty_rects); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_present, void, api::effect_runtime *runtime); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_begin_effects, void, api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_finish_effects, void, api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_reloaded_effects, void, api::effect_runtime *runtime); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_set_uniform_value, bool, api::effect_runtime *runtime, api::effect_uniform_variable variable, const void *data, size_t size); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_set_technique_state, bool, api::effect_runtime *runtime, api::effect_technique technique, bool enabled); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_overlay, void, api::effect_runtime *runtime); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_screenshot, void, api::effect_runtime *runtime, const char *path); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_render_technique, void, api::effect_runtime *runtime, api::effect_technique technique, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb); + + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_set_current_preset_path, void, api::effect_runtime *runtime, const char *path); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_reorder_techniques, bool, api::effect_runtime *runtime, size_t count, api::effect_technique *techniques); +} diff --git a/lib/reshade/include/reshade_overlay.hpp b/lib/reshade/include/reshade_overlay.hpp new file mode 100644 index 000000000..a68ffaefc --- /dev/null +++ b/lib/reshade/include/reshade_overlay.hpp @@ -0,0 +1,870 @@ +/* + * Copyright (C) 2021 Patrick Mours + * Copyright (C) 2014-2023 Omar Cornut + * SPDX-License-Identifier: BSD-3-Clause OR MIT + */ + +#if defined(IMGUI_VERSION_NUM) + +#if IMGUI_VERSION_NUM != 18971 +#error Unexpected ImGui version, please update the "imgui.h" header to version 18971! +#endif + +// Check that the 'ImTextureID' type has the same size as 'reshade::api::resource_view' +static_assert(sizeof(ImTextureID) == 8, "missing \"#define ImTextureID ImU64\" before \"#include \""); + +struct imgui_function_table_18971 +{ + ImGuiIO&(*GetIO)(); + ImGuiStyle&(*GetStyle)(); + const char*(*GetVersion)(); + bool(*Begin)(const char* name, bool* p_open, ImGuiWindowFlags flags); + void(*End)(); + bool(*BeginChild)(const char* str_id, const ImVec2& size, bool border, ImGuiWindowFlags flags); + bool(*BeginChild2)(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags flags); + void(*EndChild)(); + bool(*IsWindowAppearing)(); + bool(*IsWindowCollapsed)(); + bool(*IsWindowFocused)(ImGuiFocusedFlags flags); + bool(*IsWindowHovered)(ImGuiHoveredFlags flags); + ImDrawList*(*GetWindowDrawList)(); + float(*GetWindowDpiScale)(); + ImVec2(*GetWindowPos)(); + ImVec2(*GetWindowSize)(); + float(*GetWindowWidth)(); + float(*GetWindowHeight)(); + void(*SetNextWindowPos)(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot); + void(*SetNextWindowSize)(const ImVec2& size, ImGuiCond cond); + void(*SetNextWindowSizeConstraints)(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data); + void(*SetNextWindowContentSize)(const ImVec2& size); + void(*SetNextWindowCollapsed)(bool collapsed, ImGuiCond cond); + void(*SetNextWindowFocus)(); + void(*SetNextWindowScroll)(const ImVec2& scroll); + void(*SetNextWindowBgAlpha)(float alpha); + void(*SetWindowPos)(const ImVec2& pos, ImGuiCond cond); + void(*SetWindowSize)(const ImVec2& size, ImGuiCond cond); + void(*SetWindowCollapsed)(bool collapsed, ImGuiCond cond); + void(*SetWindowFocus)(); + void(*SetWindowFontScale)(float scale); + void(*SetWindowPos2)(const char* name, const ImVec2& pos, ImGuiCond cond); + void(*SetWindowSize2)(const char* name, const ImVec2& size, ImGuiCond cond); + void(*SetWindowCollapsed2)(const char* name, bool collapsed, ImGuiCond cond); + void(*SetWindowFocus2)(const char* name); + ImVec2(*GetContentRegionAvail)(); + ImVec2(*GetContentRegionMax)(); + ImVec2(*GetWindowContentRegionMin)(); + ImVec2(*GetWindowContentRegionMax)(); + float(*GetScrollX)(); + float(*GetScrollY)(); + void(*SetScrollX)(float scroll_x); + void(*SetScrollY)(float scroll_y); + float(*GetScrollMaxX)(); + float(*GetScrollMaxY)(); + void(*SetScrollHereX)(float center_x_ratio); + void(*SetScrollHereY)(float center_y_ratio); + void(*SetScrollFromPosX)(float local_x, float center_x_ratio); + void(*SetScrollFromPosY)(float local_y, float center_y_ratio); + void(*PushFont)(ImFont* font); + void(*PopFont)(); + void(*PushStyleColor)(ImGuiCol idx, ImU32 col); + void(*PushStyleColor2)(ImGuiCol idx, const ImVec4& col); + void(*PopStyleColor)(int count); + void(*PushStyleVar)(ImGuiStyleVar idx, float val); + void(*PushStyleVar2)(ImGuiStyleVar idx, const ImVec2& val); + void(*PopStyleVar)(int count); + void(*PushTabStop)(bool tab_stop); + void(*PopTabStop)(); + void(*PushButtonRepeat)(bool repeat); + void(*PopButtonRepeat)(); + void(*PushItemWidth)(float item_width); + void(*PopItemWidth)(); + void(*SetNextItemWidth)(float item_width); + float(*CalcItemWidth)(); + void(*PushTextWrapPos)(float wrap_local_pos_x); + void(*PopTextWrapPos)(); + ImFont*(*GetFont)(); + float(*GetFontSize)(); + ImVec2(*GetFontTexUvWhitePixel)(); + ImU32(*GetColorU32)(ImGuiCol idx, float alpha_mul); + ImU32(*GetColorU322)(const ImVec4& col); + ImU32(*GetColorU323)(ImU32 col); + const ImVec4&(*GetStyleColorVec4)(ImGuiCol idx); + void(*Separator)(); + void(*SameLine)(float offset_from_start_x, float spacing); + void(*NewLine)(); + void(*Spacing)(); + void(*Dummy)(const ImVec2& size); + void(*Indent)(float indent_w); + void(*Unindent)(float indent_w); + void(*BeginGroup)(); + void(*EndGroup)(); + ImVec2(*GetCursorPos)(); + float(*GetCursorPosX)(); + float(*GetCursorPosY)(); + void(*SetCursorPos)(const ImVec2& local_pos); + void(*SetCursorPosX)(float local_x); + void(*SetCursorPosY)(float local_y); + ImVec2(*GetCursorStartPos)(); + ImVec2(*GetCursorScreenPos)(); + void(*SetCursorScreenPos)(const ImVec2& pos); + void(*AlignTextToFramePadding)(); + float(*GetTextLineHeight)(); + float(*GetTextLineHeightWithSpacing)(); + float(*GetFrameHeight)(); + float(*GetFrameHeightWithSpacing)(); + void(*PushID)(const char* str_id); + void(*PushID2)(const char* str_id_begin, const char* str_id_end); + void(*PushID3)(const void* ptr_id); + void(*PushID4)(int int_id); + void(*PopID)(); + ImGuiID(*GetID)(const char* str_id); + ImGuiID(*GetID2)(const char* str_id_begin, const char* str_id_end); + ImGuiID(*GetID3)(const void* ptr_id); + void(*TextUnformatted)(const char* text, const char* text_end); + void(*TextV)(const char* fmt, va_list args); + void(*TextColoredV)(const ImVec4& col, const char* fmt, va_list args); + void(*TextDisabledV)(const char* fmt, va_list args); + void(*TextWrappedV)(const char* fmt, va_list args); + void(*LabelTextV)(const char* label, const char* fmt, va_list args); + void(*BulletTextV)(const char* fmt, va_list args); + void(*SeparatorText)(const char* label); + bool(*Button)(const char* label, const ImVec2& size); + bool(*SmallButton)(const char* label); + bool(*InvisibleButton)(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags); + bool(*ArrowButton)(const char* str_id, ImGuiDir dir); + bool(*Checkbox)(const char* label, bool* v); + bool(*CheckboxFlags)(const char* label, int* flags, int flags_value); + bool(*CheckboxFlags2)(const char* label, unsigned int* flags, unsigned int flags_value); + bool(*RadioButton)(const char* label, bool active); + bool(*RadioButton2)(const char* label, int* v, int v_button); + void(*ProgressBar)(float fraction, const ImVec2& size_arg, const char* overlay); + void(*Bullet)(); + void(*Image)(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); + bool(*ImageButton)(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col); + bool(*BeginCombo)(const char* label, const char* preview_value, ImGuiComboFlags flags); + void(*EndCombo)(); + bool(*Combo)(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items); + bool(*Combo2)(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items); + bool(*Combo3)(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items); + bool(*DragFloat)(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragFloat2)(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragFloat3)(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragFloat4)(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragFloatRange2)(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags); + bool(*DragInt)(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragInt2)(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragInt3)(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragInt4)(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*DragIntRange2)(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags); + bool(*DragScalar)(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + bool(*DragScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderFloat)(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderFloat2)(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderFloat3)(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderFloat4)(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderAngle)(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderInt)(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderInt2)(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderInt3)(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderInt4)(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderScalar)(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + bool(*SliderScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + bool(*VSliderFloat)(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags); + bool(*VSliderInt)(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags); + bool(*VSliderScalar)(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); + bool(*InputText)(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); + bool(*InputTextMultiline)(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); + bool(*InputTextWithHint)(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data); + bool(*InputFloat)(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags); + bool(*InputFloat2)(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags); + bool(*InputFloat3)(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags); + bool(*InputFloat4)(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags); + bool(*InputInt)(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags); + bool(*InputInt2)(const char* label, int v[2], ImGuiInputTextFlags flags); + bool(*InputInt3)(const char* label, int v[3], ImGuiInputTextFlags flags); + bool(*InputInt4)(const char* label, int v[4], ImGuiInputTextFlags flags); + bool(*InputDouble)(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags); + bool(*InputScalar)(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags); + bool(*InputScalarN)(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags); + bool(*ColorEdit3)(const char* label, float col[3], ImGuiColorEditFlags flags); + bool(*ColorEdit4)(const char* label, float col[4], ImGuiColorEditFlags flags); + bool(*ColorPicker3)(const char* label, float col[3], ImGuiColorEditFlags flags); + bool(*ColorPicker4)(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col); + bool(*ColorButton)(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, const ImVec2& size); + void(*SetColorEditOptions)(ImGuiColorEditFlags flags); + bool(*TreeNode)(const char* label); + bool(*TreeNodeV)(const char* str_id, const char* fmt, va_list args); + bool(*TreeNodeV2)(const void* ptr_id, const char* fmt, va_list args); + bool(*TreeNodeEx)(const char* label, ImGuiTreeNodeFlags flags); + bool(*TreeNodeExV)(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); + bool(*TreeNodeExV2)(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args); + void(*TreePush)(const char* str_id); + void(*TreePush2)(const void* ptr_id); + void(*TreePop)(); + float(*GetTreeNodeToLabelSpacing)(); + bool(*CollapsingHeader)(const char* label, ImGuiTreeNodeFlags flags); + bool(*CollapsingHeader2)(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags); + void(*SetNextItemOpen)(bool is_open, ImGuiCond cond); + bool(*Selectable)(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size); + bool(*Selectable2)(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size); + bool(*BeginListBox)(const char* label, const ImVec2& size); + void(*EndListBox)(); + bool(*ListBox)(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items); + bool(*ListBox2)(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items); + void(*PlotLines)(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride); + void(*PlotLines2)(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); + void(*PlotHistogram)(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride); + void(*PlotHistogram2)(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); + void(*Value)(const char* prefix, bool b); + void(*Value2)(const char* prefix, int v); + void(*Value3)(const char* prefix, unsigned int v); + void(*Value4)(const char* prefix, float v, const char* float_format); + bool(*BeginMenuBar)(); + void(*EndMenuBar)(); + bool(*BeginMainMenuBar)(); + void(*EndMainMenuBar)(); + bool(*BeginMenu)(const char* label, bool enabled); + void(*EndMenu)(); + bool(*MenuItem)(const char* label, const char* shortcut, bool selected, bool enabled); + bool(*MenuItem2)(const char* label, const char* shortcut, bool* p_selected, bool enabled); + bool(*BeginTooltip)(); + void(*EndTooltip)(); + void(*SetTooltipV)(const char* fmt, va_list args); + bool(*BeginItemTooltip)(); + void(*SetItemTooltipV)(const char* fmt, va_list args); + bool(*BeginPopup)(const char* str_id, ImGuiWindowFlags flags); + bool(*BeginPopupModal)(const char* name, bool* p_open, ImGuiWindowFlags flags); + void(*EndPopup)(); + void(*OpenPopup)(const char* str_id, ImGuiPopupFlags popup_flags); + void(*OpenPopup2)(ImGuiID id, ImGuiPopupFlags popup_flags); + void(*OpenPopupOnItemClick)(const char* str_id, ImGuiPopupFlags popup_flags); + void(*CloseCurrentPopup)(); + bool(*BeginPopupContextItem)(const char* str_id, ImGuiPopupFlags popup_flags); + bool(*BeginPopupContextWindow)(const char* str_id, ImGuiPopupFlags popup_flags); + bool(*BeginPopupContextVoid)(const char* str_id, ImGuiPopupFlags popup_flags); + bool(*IsPopupOpen)(const char* str_id, ImGuiPopupFlags flags); + bool(*BeginTable)(const char* str_id, int column, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width); + void(*EndTable)(); + void(*TableNextRow)(ImGuiTableRowFlags row_flags, float min_row_height); + bool(*TableNextColumn)(); + bool(*TableSetColumnIndex)(int column_n); + void(*TableSetupColumn)(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id); + void(*TableSetupScrollFreeze)(int cols, int rows); + void(*TableHeadersRow)(); + void(*TableHeader)(const char* label); + ImGuiTableSortSpecs*(*TableGetSortSpecs)(); + int(*TableGetColumnCount)(); + int(*TableGetColumnIndex)(); + int(*TableGetRowIndex)(); + const char*(*TableGetColumnName)(int column_n); + ImGuiTableColumnFlags(*TableGetColumnFlags)(int column_n); + void(*TableSetColumnEnabled)(int column_n, bool v); + void(*TableSetBgColor)(ImGuiTableBgTarget target, ImU32 color, int column_n); + void(*Columns)(int count, const char* id, bool border); + void(*NextColumn)(); + int(*GetColumnIndex)(); + float(*GetColumnWidth)(int column_index); + void(*SetColumnWidth)(int column_index, float width); + float(*GetColumnOffset)(int column_index); + void(*SetColumnOffset)(int column_index, float offset_x); + int(*GetColumnsCount)(); + bool(*BeginTabBar)(const char* str_id, ImGuiTabBarFlags flags); + void(*EndTabBar)(); + bool(*BeginTabItem)(const char* label, bool* p_open, ImGuiTabItemFlags flags); + void(*EndTabItem)(); + bool(*TabItemButton)(const char* label, ImGuiTabItemFlags flags); + void(*SetTabItemClosed)(const char* tab_or_docked_window_label); + ImGuiID(*DockSpace)(ImGuiID id, const ImVec2& size, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class); + void(*SetNextWindowDockID)(ImGuiID dock_id, ImGuiCond cond); + void(*SetNextWindowClass)(const ImGuiWindowClass* window_class); + ImGuiID(*GetWindowDockID)(); + bool(*IsWindowDocked)(); + bool(*BeginDragDropSource)(ImGuiDragDropFlags flags); + bool(*SetDragDropPayload)(const char* type, const void* data, size_t sz, ImGuiCond cond); + void(*EndDragDropSource)(); + bool(*BeginDragDropTarget)(); + const ImGuiPayload*(*AcceptDragDropPayload)(const char* type, ImGuiDragDropFlags flags); + void(*EndDragDropTarget)(); + const ImGuiPayload*(*GetDragDropPayload)(); + void(*BeginDisabled)(bool disabled); + void(*EndDisabled)(); + void(*PushClipRect)(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); + void(*PopClipRect)(); + void(*SetItemDefaultFocus)(); + void(*SetKeyboardFocusHere)(int offset); + void(*SetNextItemAllowOverlap)(); + bool(*IsItemHovered)(ImGuiHoveredFlags flags); + bool(*IsItemActive)(); + bool(*IsItemFocused)(); + bool(*IsItemClicked)(ImGuiMouseButton mouse_button); + bool(*IsItemVisible)(); + bool(*IsItemEdited)(); + bool(*IsItemActivated)(); + bool(*IsItemDeactivated)(); + bool(*IsItemDeactivatedAfterEdit)(); + bool(*IsItemToggledOpen)(); + bool(*IsAnyItemHovered)(); + bool(*IsAnyItemActive)(); + bool(*IsAnyItemFocused)(); + ImGuiID(*GetItemID)(); + ImVec2(*GetItemRectMin)(); + ImVec2(*GetItemRectMax)(); + ImVec2(*GetItemRectSize)(); + ImDrawList*(*GetBackgroundDrawList)(); + ImDrawList*(*GetForegroundDrawList)(); + ImDrawList*(*GetBackgroundDrawList2)(ImGuiViewport* viewport); + ImDrawList*(*GetForegroundDrawList2)(ImGuiViewport* viewport); + bool(*IsRectVisible)(const ImVec2& size); + bool(*IsRectVisible2)(const ImVec2& rect_min, const ImVec2& rect_max); + double(*GetTime)(); + int(*GetFrameCount)(); + ImDrawListSharedData*(*GetDrawListSharedData)(); + const char*(*GetStyleColorName)(ImGuiCol idx); + void(*SetStateStorage)(ImGuiStorage* storage); + ImGuiStorage*(*GetStateStorage)(); + bool(*BeginChildFrame)(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags); + void(*EndChildFrame)(); + ImVec2(*CalcTextSize)(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width); + ImVec4(*ColorConvertU32ToFloat4)(ImU32 in); + ImU32(*ColorConvertFloat4ToU32)(const ImVec4& in); + void(*ColorConvertRGBtoHSV)(float r, float g, float b, float& out_h, float& out_s, float& out_v); + void(*ColorConvertHSVtoRGB)(float h, float s, float v, float& out_r, float& out_g, float& out_b); + bool(*IsKeyDown)(ImGuiKey key); + bool(*IsKeyPressed)(ImGuiKey key, bool repeat); + bool(*IsKeyReleased)(ImGuiKey key); + int(*GetKeyPressedAmount)(ImGuiKey key, float repeat_delay, float rate); + const char*(*GetKeyName)(ImGuiKey key); + void(*SetNextFrameWantCaptureKeyboard)(bool want_capture_keyboard); + bool(*IsMouseDown)(ImGuiMouseButton button); + bool(*IsMouseClicked)(ImGuiMouseButton button, bool repeat); + bool(*IsMouseReleased)(ImGuiMouseButton button); + bool(*IsMouseDoubleClicked)(ImGuiMouseButton button); + int(*GetMouseClickedCount)(ImGuiMouseButton button); + bool(*IsMouseHoveringRect)(const ImVec2& r_min, const ImVec2& r_max, bool clip); + bool(*IsMousePosValid)(const ImVec2* mouse_pos); + bool(*IsAnyMouseDown)(); + ImVec2(*GetMousePos)(); + ImVec2(*GetMousePosOnOpeningCurrentPopup)(); + bool(*IsMouseDragging)(ImGuiMouseButton button, float lock_threshold); + ImVec2(*GetMouseDragDelta)(ImGuiMouseButton button, float lock_threshold); + void(*ResetMouseDragDelta)(ImGuiMouseButton button); + ImGuiMouseCursor(*GetMouseCursor)(); + void(*SetMouseCursor)(ImGuiMouseCursor cursor_type); + void(*SetNextFrameWantCaptureMouse)(bool want_capture_mouse); + const char*(*GetClipboardText)(); + void(*SetClipboardText)(const char* text); + void(*SetAllocatorFunctions)(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data); + void(*GetAllocatorFunctions)(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data); + void*(*MemAlloc)(size_t size); + void(*MemFree)(void* ptr); + int(*ImGuiStorage_GetInt)(const ImGuiStorage *_this, ImGuiID key, int default_val); + void(*ImGuiStorage_SetInt)(ImGuiStorage *_this, ImGuiID key, int val); + bool(*ImGuiStorage_GetBool)(const ImGuiStorage *_this, ImGuiID key, bool default_val); + void(*ImGuiStorage_SetBool)(ImGuiStorage *_this, ImGuiID key, bool val); + float(*ImGuiStorage_GetFloat)(const ImGuiStorage *_this, ImGuiID key, float default_val); + void(*ImGuiStorage_SetFloat)(ImGuiStorage *_this, ImGuiID key, float val); + void*(*ImGuiStorage_GetVoidPtr)(const ImGuiStorage *_this, ImGuiID key); + void(*ImGuiStorage_SetVoidPtr)(ImGuiStorage *_this, ImGuiID key, void* val); + int*(*ImGuiStorage_GetIntRef)(ImGuiStorage *_this, ImGuiID key, int default_val); + bool*(*ImGuiStorage_GetBoolRef)(ImGuiStorage *_this, ImGuiID key, bool default_val); + float*(*ImGuiStorage_GetFloatRef)(ImGuiStorage *_this, ImGuiID key, float default_val); + void**(*ImGuiStorage_GetVoidPtrRef)(ImGuiStorage *_this, ImGuiID key, void* default_val); + void(*ImGuiStorage_SetAllInt)(ImGuiStorage *_this, int val); + void(*ImGuiStorage_BuildSortByKey)(ImGuiStorage *_this); + void(*ConstructImGuiListClipper)(ImGuiListClipper *_this); + void(*DestructImGuiListClipper)(ImGuiListClipper *_this); + void(*ImGuiListClipper_Begin)(ImGuiListClipper *_this, int items_count, float items_height); + void(*ImGuiListClipper_End)(ImGuiListClipper *_this); + bool(*ImGuiListClipper_Step)(ImGuiListClipper *_this); + void(*ImGuiListClipper_IncludeRangeByIndices)(ImGuiListClipper *_this, int item_begin, int item_end); + void(*ImDrawList_PushClipRect)(ImDrawList *_this, const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); + void(*ImDrawList_PushClipRectFullScreen)(ImDrawList *_this); + void(*ImDrawList_PopClipRect)(ImDrawList *_this); + void(*ImDrawList_PushTextureID)(ImDrawList *_this, ImTextureID texture_id); + void(*ImDrawList_PopTextureID)(ImDrawList *_this); + void(*ImDrawList_AddLine)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness); + void(*ImDrawList_AddRect)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness); + void(*ImDrawList_AddRectFilled)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags); + void(*ImDrawList_AddRectFilledMultiColor)(ImDrawList *_this, const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); + void(*ImDrawList_AddQuad)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness); + void(*ImDrawList_AddQuadFilled)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col); + void(*ImDrawList_AddTriangle)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness); + void(*ImDrawList_AddTriangleFilled)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col); + void(*ImDrawList_AddCircle)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness); + void(*ImDrawList_AddCircleFilled)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments); + void(*ImDrawList_AddNgon)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness); + void(*ImDrawList_AddNgonFilled)(ImDrawList *_this, const ImVec2& center, float radius, ImU32 col, int num_segments); + void(*ImDrawList_AddText)(ImDrawList *_this, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end); + void(*ImDrawList_AddText2)(ImDrawList *_this, const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect); + void(*ImDrawList_AddPolyline)(ImDrawList *_this, const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); + void(*ImDrawList_AddConvexPolyFilled)(ImDrawList *_this, const ImVec2* points, int num_points, ImU32 col); + void(*ImDrawList_AddBezierCubic)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments); + void(*ImDrawList_AddBezierQuadratic)(ImDrawList *_this, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments); + void(*ImDrawList_AddImage)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col); + void(*ImDrawList_AddImageQuad)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1, const ImVec2& uv2, const ImVec2& uv3, const ImVec2& uv4, ImU32 col); + void(*ImDrawList_AddImageRounded)(ImDrawList *_this, ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags); + void(*ImDrawList_PathArcTo)(ImDrawList *_this, const ImVec2& center, float radius, float a_min, float a_max, int num_segments); + void(*ImDrawList_PathArcToFast)(ImDrawList *_this, const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); + void(*ImDrawList_PathBezierCubicCurveTo)(ImDrawList *_this, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments); + void(*ImDrawList_PathBezierQuadraticCurveTo)(ImDrawList *_this, const ImVec2& p2, const ImVec2& p3, int num_segments); + void(*ImDrawList_PathRect)(ImDrawList *_this, const ImVec2& rect_min, const ImVec2& rect_max, float rounding, ImDrawFlags flags); + void(*ImDrawList_AddCallback)(ImDrawList *_this, ImDrawCallback callback, void* callback_data); + void(*ImDrawList_AddDrawCmd)(ImDrawList *_this); + ImDrawList*(*ImDrawList_CloneOutput)(const ImDrawList *_this); + void(*ImDrawList_PrimReserve)(ImDrawList *_this, int idx_count, int vtx_count); + void(*ImDrawList_PrimUnreserve)(ImDrawList *_this, int idx_count, int vtx_count); + void(*ImDrawList_PrimRect)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, ImU32 col); + void(*ImDrawList_PrimRectUV)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + void(*ImDrawList_PrimQuadUV)(ImDrawList *_this, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col); + void(*ConstructImFont)(ImFont *_this); + void(*DestructImFont)(ImFont *_this); + const ImFontGlyph*(*ImFont_FindGlyph)(const ImFont *_this, ImWchar c); + const ImFontGlyph*(*ImFont_FindGlyphNoFallback)(const ImFont *_this, ImWchar c); + ImVec2(*ImFont_CalcTextSizeA)(const ImFont *_this, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining); + const char*(*ImFont_CalcWordWrapPositionA)(const ImFont *_this, float scale, const char* text, const char* text_end, float wrap_width); + void(*ImFont_RenderChar)(const ImFont *_this, ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c); + void(*ImFont_RenderText)(const ImFont *_this, ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip); + +}; + +using imgui_function_table = imgui_function_table_18971; + +inline const imgui_function_table *&imgui_function_table_instance() +{ + static const imgui_function_table *instance = nullptr; + return instance; +} + +#ifndef RESHADE_API_LIBRARY_EXPORT + +namespace ImGui +{ + inline ImGuiIO& GetIO() { return imgui_function_table_instance()->GetIO(); } + inline ImGuiStyle& GetStyle() { return imgui_function_table_instance()->GetStyle(); } + inline const char* GetVersion() { return imgui_function_table_instance()->GetVersion(); } + inline bool Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { return imgui_function_table_instance()->Begin(name, p_open, flags); } + inline void End() { imgui_function_table_instance()->End(); } + inline bool BeginChild(const char* str_id, const ImVec2& size, bool border, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChild(str_id, size, border, flags); } + inline bool BeginChild(ImGuiID id, const ImVec2& size, bool border, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChild2(id, size, border, flags); } + inline void EndChild() { imgui_function_table_instance()->EndChild(); } + inline bool IsWindowAppearing() { return imgui_function_table_instance()->IsWindowAppearing(); } + inline bool IsWindowCollapsed() { return imgui_function_table_instance()->IsWindowCollapsed(); } + inline bool IsWindowFocused(ImGuiFocusedFlags flags) { return imgui_function_table_instance()->IsWindowFocused(flags); } + inline bool IsWindowHovered(ImGuiHoveredFlags flags) { return imgui_function_table_instance()->IsWindowHovered(flags); } + inline ImDrawList* GetWindowDrawList() { return imgui_function_table_instance()->GetWindowDrawList(); } + inline float GetWindowDpiScale() { return imgui_function_table_instance()->GetWindowDpiScale(); } + inline ImVec2 GetWindowPos() { return imgui_function_table_instance()->GetWindowPos(); } + inline ImVec2 GetWindowSize() { return imgui_function_table_instance()->GetWindowSize(); } + inline float GetWindowWidth() { return imgui_function_table_instance()->GetWindowWidth(); } + inline float GetWindowHeight() { return imgui_function_table_instance()->GetWindowHeight(); } + inline void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { imgui_function_table_instance()->SetNextWindowPos(pos, cond, pivot); } + inline void SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowSize(size, cond); } + inline void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_data) { imgui_function_table_instance()->SetNextWindowSizeConstraints(size_min, size_max, custom_callback, custom_callback_data); } + inline void SetNextWindowContentSize(const ImVec2& size) { imgui_function_table_instance()->SetNextWindowContentSize(size); } + inline void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowCollapsed(collapsed, cond); } + inline void SetNextWindowFocus() { imgui_function_table_instance()->SetNextWindowFocus(); } + inline void SetNextWindowScroll(const ImVec2& scroll) { imgui_function_table_instance()->SetNextWindowScroll(scroll); } + inline void SetNextWindowBgAlpha(float alpha) { imgui_function_table_instance()->SetNextWindowBgAlpha(alpha); } + inline void SetWindowPos(const ImVec2& pos, ImGuiCond cond) { imgui_function_table_instance()->SetWindowPos(pos, cond); } + inline void SetWindowSize(const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetWindowSize(size, cond); } + inline void SetWindowCollapsed(bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetWindowCollapsed(collapsed, cond); } + inline void SetWindowFocus() { imgui_function_table_instance()->SetWindowFocus(); } + inline void SetWindowFontScale(float scale) { imgui_function_table_instance()->SetWindowFontScale(scale); } + inline void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond) { imgui_function_table_instance()->SetWindowPos2(name, pos, cond); } + inline void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) { imgui_function_table_instance()->SetWindowSize2(name, size, cond); } + inline void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) { imgui_function_table_instance()->SetWindowCollapsed2(name, collapsed, cond); } + inline void SetWindowFocus(const char* name) { imgui_function_table_instance()->SetWindowFocus2(name); } + inline ImVec2 GetContentRegionAvail() { return imgui_function_table_instance()->GetContentRegionAvail(); } + inline ImVec2 GetContentRegionMax() { return imgui_function_table_instance()->GetContentRegionMax(); } + inline ImVec2 GetWindowContentRegionMin() { return imgui_function_table_instance()->GetWindowContentRegionMin(); } + inline ImVec2 GetWindowContentRegionMax() { return imgui_function_table_instance()->GetWindowContentRegionMax(); } + inline float GetScrollX() { return imgui_function_table_instance()->GetScrollX(); } + inline float GetScrollY() { return imgui_function_table_instance()->GetScrollY(); } + inline void SetScrollX(float scroll_x) { imgui_function_table_instance()->SetScrollX(scroll_x); } + inline void SetScrollY(float scroll_y) { imgui_function_table_instance()->SetScrollY(scroll_y); } + inline float GetScrollMaxX() { return imgui_function_table_instance()->GetScrollMaxX(); } + inline float GetScrollMaxY() { return imgui_function_table_instance()->GetScrollMaxY(); } + inline void SetScrollHereX(float center_x_ratio) { imgui_function_table_instance()->SetScrollHereX(center_x_ratio); } + inline void SetScrollHereY(float center_y_ratio) { imgui_function_table_instance()->SetScrollHereY(center_y_ratio); } + inline void SetScrollFromPosX(float local_x, float center_x_ratio) { imgui_function_table_instance()->SetScrollFromPosX(local_x, center_x_ratio); } + inline void SetScrollFromPosY(float local_y, float center_y_ratio) { imgui_function_table_instance()->SetScrollFromPosY(local_y, center_y_ratio); } + inline void PushFont(ImFont* font) { imgui_function_table_instance()->PushFont(font); } + inline void PopFont() { imgui_function_table_instance()->PopFont(); } + inline void PushStyleColor(ImGuiCol idx, ImU32 col) { imgui_function_table_instance()->PushStyleColor(idx, col); } + inline void PushStyleColor(ImGuiCol idx, const ImVec4& col) { imgui_function_table_instance()->PushStyleColor2(idx, col); } + inline void PopStyleColor(int count) { imgui_function_table_instance()->PopStyleColor(count); } + inline void PushStyleVar(ImGuiStyleVar idx, float val) { imgui_function_table_instance()->PushStyleVar(idx, val); } + inline void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { imgui_function_table_instance()->PushStyleVar2(idx, val); } + inline void PopStyleVar(int count) { imgui_function_table_instance()->PopStyleVar(count); } + inline void PushTabStop(bool tab_stop) { imgui_function_table_instance()->PushTabStop(tab_stop); } + inline void PopTabStop() { imgui_function_table_instance()->PopTabStop(); } + inline void PushButtonRepeat(bool repeat) { imgui_function_table_instance()->PushButtonRepeat(repeat); } + inline void PopButtonRepeat() { imgui_function_table_instance()->PopButtonRepeat(); } + inline void PushItemWidth(float item_width) { imgui_function_table_instance()->PushItemWidth(item_width); } + inline void PopItemWidth() { imgui_function_table_instance()->PopItemWidth(); } + inline void SetNextItemWidth(float item_width) { imgui_function_table_instance()->SetNextItemWidth(item_width); } + inline float CalcItemWidth() { return imgui_function_table_instance()->CalcItemWidth(); } + inline void PushTextWrapPos(float wrap_local_pos_x) { imgui_function_table_instance()->PushTextWrapPos(wrap_local_pos_x); } + inline void PopTextWrapPos() { imgui_function_table_instance()->PopTextWrapPos(); } + inline ImFont* GetFont() { return imgui_function_table_instance()->GetFont(); } + inline float GetFontSize() { return imgui_function_table_instance()->GetFontSize(); } + inline ImVec2 GetFontTexUvWhitePixel() { return imgui_function_table_instance()->GetFontTexUvWhitePixel(); } + inline ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { return imgui_function_table_instance()->GetColorU32(idx, alpha_mul); } + inline ImU32 GetColorU32(const ImVec4& col) { return imgui_function_table_instance()->GetColorU322(col); } + inline ImU32 GetColorU32(ImU32 col) { return imgui_function_table_instance()->GetColorU323(col); } + inline const ImVec4& GetStyleColorVec4(ImGuiCol idx) { return imgui_function_table_instance()->GetStyleColorVec4(idx); } + inline void Separator() { imgui_function_table_instance()->Separator(); } + inline void SameLine(float offset_from_start_x, float spacing) { imgui_function_table_instance()->SameLine(offset_from_start_x, spacing); } + inline void NewLine() { imgui_function_table_instance()->NewLine(); } + inline void Spacing() { imgui_function_table_instance()->Spacing(); } + inline void Dummy(const ImVec2& size) { imgui_function_table_instance()->Dummy(size); } + inline void Indent(float indent_w) { imgui_function_table_instance()->Indent(indent_w); } + inline void Unindent(float indent_w) { imgui_function_table_instance()->Unindent(indent_w); } + inline void BeginGroup() { imgui_function_table_instance()->BeginGroup(); } + inline void EndGroup() { imgui_function_table_instance()->EndGroup(); } + inline ImVec2 GetCursorPos() { return imgui_function_table_instance()->GetCursorPos(); } + inline float GetCursorPosX() { return imgui_function_table_instance()->GetCursorPosX(); } + inline float GetCursorPosY() { return imgui_function_table_instance()->GetCursorPosY(); } + inline void SetCursorPos(const ImVec2& local_pos) { imgui_function_table_instance()->SetCursorPos(local_pos); } + inline void SetCursorPosX(float local_x) { imgui_function_table_instance()->SetCursorPosX(local_x); } + inline void SetCursorPosY(float local_y) { imgui_function_table_instance()->SetCursorPosY(local_y); } + inline ImVec2 GetCursorStartPos() { return imgui_function_table_instance()->GetCursorStartPos(); } + inline ImVec2 GetCursorScreenPos() { return imgui_function_table_instance()->GetCursorScreenPos(); } + inline void SetCursorScreenPos(const ImVec2& pos) { imgui_function_table_instance()->SetCursorScreenPos(pos); } + inline void AlignTextToFramePadding() { imgui_function_table_instance()->AlignTextToFramePadding(); } + inline float GetTextLineHeight() { return imgui_function_table_instance()->GetTextLineHeight(); } + inline float GetTextLineHeightWithSpacing() { return imgui_function_table_instance()->GetTextLineHeightWithSpacing(); } + inline float GetFrameHeight() { return imgui_function_table_instance()->GetFrameHeight(); } + inline float GetFrameHeightWithSpacing() { return imgui_function_table_instance()->GetFrameHeightWithSpacing(); } + inline void PushID(const char* str_id) { imgui_function_table_instance()->PushID(str_id); } + inline void PushID(const char* str_id_begin, const char* str_id_end) { imgui_function_table_instance()->PushID2(str_id_begin, str_id_end); } + inline void PushID(const void* ptr_id) { imgui_function_table_instance()->PushID3(ptr_id); } + inline void PushID(int int_id) { imgui_function_table_instance()->PushID4(int_id); } + inline void PopID() { imgui_function_table_instance()->PopID(); } + inline ImGuiID GetID(const char* str_id) { return imgui_function_table_instance()->GetID(str_id); } + inline ImGuiID GetID(const char* str_id_begin, const char* str_id_end) { return imgui_function_table_instance()->GetID2(str_id_begin, str_id_end); } + inline ImGuiID GetID(const void* ptr_id) { return imgui_function_table_instance()->GetID3(ptr_id); } + inline void TextUnformatted(const char* text, const char* text_end) { imgui_function_table_instance()->TextUnformatted(text, text_end); } + inline void Text(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextV(fmt, args); va_end(args); } + inline void TextV(const char* fmt, va_list args) { imgui_function_table_instance()->TextV(fmt, args); } + inline void TextColored(const ImVec4& col, const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextColoredV(col, fmt, args); va_end(args); } + inline void TextColoredV(const ImVec4& col, const char* fmt, va_list args) { imgui_function_table_instance()->TextColoredV(col, fmt, args); } + inline void TextDisabled(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextDisabledV(fmt, args); va_end(args); } + inline void TextDisabledV(const char* fmt, va_list args) { imgui_function_table_instance()->TextDisabledV(fmt, args); } + inline void TextWrapped(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->TextWrappedV(fmt, args); va_end(args); } + inline void TextWrappedV(const char* fmt, va_list args) { imgui_function_table_instance()->TextWrappedV(fmt, args); } + inline void LabelText(const char* label, const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->LabelTextV(label, fmt, args); va_end(args); } + inline void LabelTextV(const char* label, const char* fmt, va_list args) { imgui_function_table_instance()->LabelTextV(label, fmt, args); } + inline void BulletText(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->BulletTextV(fmt, args); va_end(args); } + inline void BulletTextV(const char* fmt, va_list args) { imgui_function_table_instance()->BulletTextV(fmt, args); } + inline void SeparatorText(const char* label) { imgui_function_table_instance()->SeparatorText(label); } + inline bool Button(const char* label, const ImVec2& size) { return imgui_function_table_instance()->Button(label, size); } + inline bool SmallButton(const char* label) { return imgui_function_table_instance()->SmallButton(label); } + inline bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags) { return imgui_function_table_instance()->InvisibleButton(str_id, size, flags); } + inline bool ArrowButton(const char* str_id, ImGuiDir dir) { return imgui_function_table_instance()->ArrowButton(str_id, dir); } + inline bool Checkbox(const char* label, bool* v) { return imgui_function_table_instance()->Checkbox(label, v); } + inline bool CheckboxFlags(const char* label, int* flags, int flags_value) { return imgui_function_table_instance()->CheckboxFlags(label, flags, flags_value); } + inline bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) { return imgui_function_table_instance()->CheckboxFlags2(label, flags, flags_value); } + inline bool RadioButton(const char* label, bool active) { return imgui_function_table_instance()->RadioButton(label, active); } + inline bool RadioButton(const char* label, int* v, int v_button) { return imgui_function_table_instance()->RadioButton2(label, v, v_button); } + inline void ProgressBar(float fraction, const ImVec2& size_arg, const char* overlay) { imgui_function_table_instance()->ProgressBar(fraction, size_arg, overlay); } + inline void Bullet() { imgui_function_table_instance()->Bullet(); } + inline void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) { imgui_function_table_instance()->Image(user_texture_id, size, uv0, uv1, tint_col, border_col); } + inline bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col) { return imgui_function_table_instance()->ImageButton(str_id, user_texture_id, size, uv0, uv1, bg_col, tint_col); } + inline bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags) { return imgui_function_table_instance()->BeginCombo(label, preview_value, flags); } + inline void EndCombo() { imgui_function_table_instance()->EndCombo(); } + inline bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo(label, current_item, items, items_count, popup_max_height_in_items); } + inline bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo2(label, current_item, items_separated_by_zeros, popup_max_height_in_items); } + inline bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items) { return imgui_function_table_instance()->Combo3(label, current_item, items_getter, data, items_count, popup_max_height_in_items); } + inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat2(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat3(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloat4(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragFloatRange2(label, v_current_min, v_current_max, v_speed, v_min, v_max, format, format_max, flags); } + inline bool DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt2(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt3(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragInt4(label, v, v_speed, v_min, v_max, format, flags); } + inline bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragIntRange2(label, v_current_min, v_current_max, v_speed, v_min, v_max, format, format_max, flags); } + inline bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragScalar(label, data_type, p_data, v_speed, p_min, p_max, format, flags); } + inline bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->DragScalarN(label, data_type, p_data, components, v_speed, p_min, p_max, format, flags); } + inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat(label, v, v_min, v_max, format, flags); } + inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat2(label, v, v_min, v_max, format, flags); } + inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat3(label, v, v_min, v_max, format, flags); } + inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderFloat4(label, v, v_min, v_max, format, flags); } + inline bool SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderAngle(label, v_rad, v_degrees_min, v_degrees_max, format, flags); } + inline bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt(label, v, v_min, v_max, format, flags); } + inline bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt2(label, v, v_min, v_max, format, flags); } + inline bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt3(label, v, v_min, v_max, format, flags); } + inline bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderInt4(label, v, v_min, v_max, format, flags); } + inline bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderScalar(label, data_type, p_data, p_min, p_max, format, flags); } + inline bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->SliderScalarN(label, data_type, p_data, components, p_min, p_max, format, flags); } + inline bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderFloat(label, size, v, v_min, v_max, format, flags); } + inline bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderInt(label, size, v, v_min, v_max, format, flags); } + inline bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags) { return imgui_function_table_instance()->VSliderScalar(label, size, data_type, p_data, p_min, p_max, format, flags); } + inline bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputText(label, buf, buf_size, flags, callback, user_data); } + inline bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputTextMultiline(label, buf, buf_size, size, flags, callback, user_data); } + inline bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { return imgui_function_table_instance()->InputTextWithHint(label, hint, buf, buf_size, flags, callback, user_data); } + inline bool InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat(label, v, step, step_fast, format, flags); } + inline bool InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat2(label, v, format, flags); } + inline bool InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat3(label, v, format, flags); } + inline bool InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputFloat4(label, v, format, flags); } + inline bool InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt(label, v, step, step_fast, flags); } + inline bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt2(label, v, flags); } + inline bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt3(label, v, flags); } + inline bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputInt4(label, v, flags); } + inline bool InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputDouble(label, v, step, step_fast, format, flags); } + inline bool InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputScalar(label, data_type, p_data, p_step, p_step_fast, format, flags); } + inline bool InputScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) { return imgui_function_table_instance()->InputScalarN(label, data_type, p_data, components, p_step, p_step_fast, format, flags); } + inline bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorEdit3(label, col, flags); } + inline bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorEdit4(label, col, flags); } + inline bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { return imgui_function_table_instance()->ColorPicker3(label, col, flags); } + inline bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) { return imgui_function_table_instance()->ColorPicker4(label, col, flags, ref_col); } + inline bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, const ImVec2& size) { return imgui_function_table_instance()->ColorButton(desc_id, col, flags, size); } + inline void SetColorEditOptions(ImGuiColorEditFlags flags) { imgui_function_table_instance()->SetColorEditOptions(flags); } + inline bool TreeNode(const char* label) { return imgui_function_table_instance()->TreeNode(label); } + inline bool TreeNode(const char* str_id, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeV(str_id, fmt, args); va_end(args); } + inline bool TreeNode(const void* ptr_id, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeV2(ptr_id, fmt, args); va_end(args); } + inline bool TreeNodeV(const char* str_id, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeV(str_id, fmt, args); } + inline bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeV2(ptr_id, fmt, args); } + inline bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->TreeNodeEx(label, flags); } + inline bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeExV(str_id, flags, fmt, args); va_end(args); } + inline bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { va_list args; va_start(args, fmt); return imgui_function_table_instance()->TreeNodeExV2(ptr_id, flags, fmt, args); va_end(args); } + inline bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeExV(str_id, flags, fmt, args); } + inline bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { return imgui_function_table_instance()->TreeNodeExV2(ptr_id, flags, fmt, args); } + inline void TreePush(const char* str_id) { imgui_function_table_instance()->TreePush(str_id); } + inline void TreePush(const void* ptr_id) { imgui_function_table_instance()->TreePush2(ptr_id); } + inline void TreePop() { imgui_function_table_instance()->TreePop(); } + inline float GetTreeNodeToLabelSpacing() { return imgui_function_table_instance()->GetTreeNodeToLabelSpacing(); } + inline bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->CollapsingHeader(label, flags); } + inline bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags) { return imgui_function_table_instance()->CollapsingHeader2(label, p_visible, flags); } + inline void SetNextItemOpen(bool is_open, ImGuiCond cond) { imgui_function_table_instance()->SetNextItemOpen(is_open, cond); } + inline bool Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size) { return imgui_function_table_instance()->Selectable(label, selected, flags, size); } + inline bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size) { return imgui_function_table_instance()->Selectable2(label, p_selected, flags, size); } + inline bool BeginListBox(const char* label, const ImVec2& size) { return imgui_function_table_instance()->BeginListBox(label, size); } + inline void EndListBox() { imgui_function_table_instance()->EndListBox(); } + inline bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items) { return imgui_function_table_instance()->ListBox(label, current_item, items, items_count, height_in_items); } + inline bool ListBox(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items) { return imgui_function_table_instance()->ListBox2(label, current_item, items_getter, data, items_count, height_in_items); } + inline void PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { imgui_function_table_instance()->PlotLines(label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride); } + inline void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { imgui_function_table_instance()->PlotLines2(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } + inline void PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { imgui_function_table_instance()->PlotHistogram(label, values, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size, stride); } + inline void PlotHistogram(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { imgui_function_table_instance()->PlotHistogram2(label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } + inline void Value(const char* prefix, bool b) { imgui_function_table_instance()->Value(prefix, b); } + inline void Value(const char* prefix, int v) { imgui_function_table_instance()->Value2(prefix, v); } + inline void Value(const char* prefix, unsigned int v) { imgui_function_table_instance()->Value3(prefix, v); } + inline void Value(const char* prefix, float v, const char* float_format) { imgui_function_table_instance()->Value4(prefix, v, float_format); } + inline bool BeginMenuBar() { return imgui_function_table_instance()->BeginMenuBar(); } + inline void EndMenuBar() { imgui_function_table_instance()->EndMenuBar(); } + inline bool BeginMainMenuBar() { return imgui_function_table_instance()->BeginMainMenuBar(); } + inline void EndMainMenuBar() { imgui_function_table_instance()->EndMainMenuBar(); } + inline bool BeginMenu(const char* label, bool enabled) { return imgui_function_table_instance()->BeginMenu(label, enabled); } + inline void EndMenu() { imgui_function_table_instance()->EndMenu(); } + inline bool MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) { return imgui_function_table_instance()->MenuItem(label, shortcut, selected, enabled); } + inline bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) { return imgui_function_table_instance()->MenuItem2(label, shortcut, p_selected, enabled); } + inline bool BeginTooltip() { return imgui_function_table_instance()->BeginTooltip(); } + inline void EndTooltip() { imgui_function_table_instance()->EndTooltip(); } + inline void SetTooltip(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->SetTooltipV(fmt, args); va_end(args); } + inline void SetTooltipV(const char* fmt, va_list args) { imgui_function_table_instance()->SetTooltipV(fmt, args); } + inline bool BeginItemTooltip() { return imgui_function_table_instance()->BeginItemTooltip(); } + inline void SetItemTooltip(const char* fmt, ...) { va_list args; va_start(args, fmt); imgui_function_table_instance()->SetItemTooltipV(fmt, args); va_end(args); } + inline void SetItemTooltipV(const char* fmt, va_list args) { imgui_function_table_instance()->SetItemTooltipV(fmt, args); } + inline bool BeginPopup(const char* str_id, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginPopup(str_id, flags); } + inline bool BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginPopupModal(name, p_open, flags); } + inline void EndPopup() { imgui_function_table_instance()->EndPopup(); } + inline void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopup(str_id, popup_flags); } + inline void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopup2(id, popup_flags); } + inline void OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags) { imgui_function_table_instance()->OpenPopupOnItemClick(str_id, popup_flags); } + inline void CloseCurrentPopup() { imgui_function_table_instance()->CloseCurrentPopup(); } + inline bool BeginPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextItem(str_id, popup_flags); } + inline bool BeginPopupContextWindow(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextWindow(str_id, popup_flags); } + inline bool BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flags) { return imgui_function_table_instance()->BeginPopupContextVoid(str_id, popup_flags); } + inline bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags) { return imgui_function_table_instance()->IsPopupOpen(str_id, flags); } + inline bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width) { return imgui_function_table_instance()->BeginTable(str_id, column, flags, outer_size, inner_width); } + inline void EndTable() { imgui_function_table_instance()->EndTable(); } + inline void TableNextRow(ImGuiTableRowFlags row_flags, float min_row_height) { imgui_function_table_instance()->TableNextRow(row_flags, min_row_height); } + inline bool TableNextColumn() { return imgui_function_table_instance()->TableNextColumn(); } + inline bool TableSetColumnIndex(int column_n) { return imgui_function_table_instance()->TableSetColumnIndex(column_n); } + inline void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) { imgui_function_table_instance()->TableSetupColumn(label, flags, init_width_or_weight, user_id); } + inline void TableSetupScrollFreeze(int cols, int rows) { imgui_function_table_instance()->TableSetupScrollFreeze(cols, rows); } + inline void TableHeadersRow() { imgui_function_table_instance()->TableHeadersRow(); } + inline void TableHeader(const char* label) { imgui_function_table_instance()->TableHeader(label); } + inline ImGuiTableSortSpecs* TableGetSortSpecs() { return imgui_function_table_instance()->TableGetSortSpecs(); } + inline int TableGetColumnCount() { return imgui_function_table_instance()->TableGetColumnCount(); } + inline int TableGetColumnIndex() { return imgui_function_table_instance()->TableGetColumnIndex(); } + inline int TableGetRowIndex() { return imgui_function_table_instance()->TableGetRowIndex(); } + inline const char* TableGetColumnName(int column_n) { return imgui_function_table_instance()->TableGetColumnName(column_n); } + inline ImGuiTableColumnFlags TableGetColumnFlags(int column_n) { return imgui_function_table_instance()->TableGetColumnFlags(column_n); } + inline void TableSetColumnEnabled(int column_n, bool v) { imgui_function_table_instance()->TableSetColumnEnabled(column_n, v); } + inline void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n) { imgui_function_table_instance()->TableSetBgColor(target, color, column_n); } + inline void Columns(int count, const char* id, bool border) { imgui_function_table_instance()->Columns(count, id, border); } + inline void NextColumn() { imgui_function_table_instance()->NextColumn(); } + inline int GetColumnIndex() { return imgui_function_table_instance()->GetColumnIndex(); } + inline float GetColumnWidth(int column_index) { return imgui_function_table_instance()->GetColumnWidth(column_index); } + inline void SetColumnWidth(int column_index, float width) { imgui_function_table_instance()->SetColumnWidth(column_index, width); } + inline float GetColumnOffset(int column_index) { return imgui_function_table_instance()->GetColumnOffset(column_index); } + inline void SetColumnOffset(int column_index, float offset_x) { imgui_function_table_instance()->SetColumnOffset(column_index, offset_x); } + inline int GetColumnsCount() { return imgui_function_table_instance()->GetColumnsCount(); } + inline bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) { return imgui_function_table_instance()->BeginTabBar(str_id, flags); } + inline void EndTabBar() { imgui_function_table_instance()->EndTabBar(); } + inline bool BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags flags) { return imgui_function_table_instance()->BeginTabItem(label, p_open, flags); } + inline void EndTabItem() { imgui_function_table_instance()->EndTabItem(); } + inline bool TabItemButton(const char* label, ImGuiTabItemFlags flags) { return imgui_function_table_instance()->TabItemButton(label, flags); } + inline void SetTabItemClosed(const char* tab_or_docked_window_label) { imgui_function_table_instance()->SetTabItemClosed(tab_or_docked_window_label); } + inline ImGuiID DockSpace(ImGuiID id, const ImVec2& size, ImGuiDockNodeFlags flags, const ImGuiWindowClass* window_class) { return imgui_function_table_instance()->DockSpace(id, size, flags, window_class); } + inline void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond) { imgui_function_table_instance()->SetNextWindowDockID(dock_id, cond); } + inline void SetNextWindowClass(const ImGuiWindowClass* window_class) { imgui_function_table_instance()->SetNextWindowClass(window_class); } + inline ImGuiID GetWindowDockID() { return imgui_function_table_instance()->GetWindowDockID(); } + inline bool IsWindowDocked() { return imgui_function_table_instance()->IsWindowDocked(); } + inline bool BeginDragDropSource(ImGuiDragDropFlags flags) { return imgui_function_table_instance()->BeginDragDropSource(flags); } + inline bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond) { return imgui_function_table_instance()->SetDragDropPayload(type, data, sz, cond); } + inline void EndDragDropSource() { imgui_function_table_instance()->EndDragDropSource(); } + inline bool BeginDragDropTarget() { return imgui_function_table_instance()->BeginDragDropTarget(); } + inline const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { return imgui_function_table_instance()->AcceptDragDropPayload(type, flags); } + inline void EndDragDropTarget() { imgui_function_table_instance()->EndDragDropTarget(); } + inline const ImGuiPayload* GetDragDropPayload() { return imgui_function_table_instance()->GetDragDropPayload(); } + inline void BeginDisabled(bool disabled) { imgui_function_table_instance()->BeginDisabled(disabled); } + inline void EndDisabled() { imgui_function_table_instance()->EndDisabled(); } + inline void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { imgui_function_table_instance()->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); } + inline void PopClipRect() { imgui_function_table_instance()->PopClipRect(); } + inline void SetItemDefaultFocus() { imgui_function_table_instance()->SetItemDefaultFocus(); } + inline void SetKeyboardFocusHere(int offset) { imgui_function_table_instance()->SetKeyboardFocusHere(offset); } + inline void SetNextItemAllowOverlap() { imgui_function_table_instance()->SetNextItemAllowOverlap(); } + inline bool IsItemHovered(ImGuiHoveredFlags flags) { return imgui_function_table_instance()->IsItemHovered(flags); } + inline bool IsItemActive() { return imgui_function_table_instance()->IsItemActive(); } + inline bool IsItemFocused() { return imgui_function_table_instance()->IsItemFocused(); } + inline bool IsItemClicked(ImGuiMouseButton mouse_button) { return imgui_function_table_instance()->IsItemClicked(mouse_button); } + inline bool IsItemVisible() { return imgui_function_table_instance()->IsItemVisible(); } + inline bool IsItemEdited() { return imgui_function_table_instance()->IsItemEdited(); } + inline bool IsItemActivated() { return imgui_function_table_instance()->IsItemActivated(); } + inline bool IsItemDeactivated() { return imgui_function_table_instance()->IsItemDeactivated(); } + inline bool IsItemDeactivatedAfterEdit() { return imgui_function_table_instance()->IsItemDeactivatedAfterEdit(); } + inline bool IsItemToggledOpen() { return imgui_function_table_instance()->IsItemToggledOpen(); } + inline bool IsAnyItemHovered() { return imgui_function_table_instance()->IsAnyItemHovered(); } + inline bool IsAnyItemActive() { return imgui_function_table_instance()->IsAnyItemActive(); } + inline bool IsAnyItemFocused() { return imgui_function_table_instance()->IsAnyItemFocused(); } + inline ImGuiID GetItemID() { return imgui_function_table_instance()->GetItemID(); } + inline ImVec2 GetItemRectMin() { return imgui_function_table_instance()->GetItemRectMin(); } + inline ImVec2 GetItemRectMax() { return imgui_function_table_instance()->GetItemRectMax(); } + inline ImVec2 GetItemRectSize() { return imgui_function_table_instance()->GetItemRectSize(); } + inline ImDrawList* GetBackgroundDrawList() { return imgui_function_table_instance()->GetBackgroundDrawList(); } + inline ImDrawList* GetForegroundDrawList() { return imgui_function_table_instance()->GetForegroundDrawList(); } + inline ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport) { return imgui_function_table_instance()->GetBackgroundDrawList2(viewport); } + inline ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport) { return imgui_function_table_instance()->GetForegroundDrawList2(viewport); } + inline bool IsRectVisible(const ImVec2& size) { return imgui_function_table_instance()->IsRectVisible(size); } + inline bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) { return imgui_function_table_instance()->IsRectVisible2(rect_min, rect_max); } + inline double GetTime() { return imgui_function_table_instance()->GetTime(); } + inline int GetFrameCount() { return imgui_function_table_instance()->GetFrameCount(); } + inline ImDrawListSharedData* GetDrawListSharedData() { return imgui_function_table_instance()->GetDrawListSharedData(); } + inline const char* GetStyleColorName(ImGuiCol idx) { return imgui_function_table_instance()->GetStyleColorName(idx); } + inline void SetStateStorage(ImGuiStorage* storage) { imgui_function_table_instance()->SetStateStorage(storage); } + inline ImGuiStorage* GetStateStorage() { return imgui_function_table_instance()->GetStateStorage(); } + inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags) { return imgui_function_table_instance()->BeginChildFrame(id, size, flags); } + inline void EndChildFrame() { imgui_function_table_instance()->EndChildFrame(); } + inline ImVec2 CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { return imgui_function_table_instance()->CalcTextSize(text, text_end, hide_text_after_double_hash, wrap_width); } + inline ImVec4 ColorConvertU32ToFloat4(ImU32 in) { return imgui_function_table_instance()->ColorConvertU32ToFloat4(in); } + inline ImU32 ColorConvertFloat4ToU32(const ImVec4& in) { return imgui_function_table_instance()->ColorConvertFloat4ToU32(in); } + inline void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) { imgui_function_table_instance()->ColorConvertRGBtoHSV(r, g, b, out_h, out_s, out_v); } + inline void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) { imgui_function_table_instance()->ColorConvertHSVtoRGB(h, s, v, out_r, out_g, out_b); } + inline bool IsKeyDown(ImGuiKey key) { return imgui_function_table_instance()->IsKeyDown(key); } + inline bool IsKeyPressed(ImGuiKey key, bool repeat) { return imgui_function_table_instance()->IsKeyPressed(key, repeat); } + inline bool IsKeyReleased(ImGuiKey key) { return imgui_function_table_instance()->IsKeyReleased(key); } + inline int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate) { return imgui_function_table_instance()->GetKeyPressedAmount(key, repeat_delay, rate); } + inline const char* GetKeyName(ImGuiKey key) { return imgui_function_table_instance()->GetKeyName(key); } + inline void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard) { imgui_function_table_instance()->SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } + inline bool IsMouseDown(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseDown(button); } + inline bool IsMouseClicked(ImGuiMouseButton button, bool repeat) { return imgui_function_table_instance()->IsMouseClicked(button, repeat); } + inline bool IsMouseReleased(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseReleased(button); } + inline bool IsMouseDoubleClicked(ImGuiMouseButton button) { return imgui_function_table_instance()->IsMouseDoubleClicked(button); } + inline int GetMouseClickedCount(ImGuiMouseButton button) { return imgui_function_table_instance()->GetMouseClickedCount(button); } + inline bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { return imgui_function_table_instance()->IsMouseHoveringRect(r_min, r_max, clip); } + inline bool IsMousePosValid(const ImVec2* mouse_pos) { return imgui_function_table_instance()->IsMousePosValid(mouse_pos); } + inline bool IsAnyMouseDown() { return imgui_function_table_instance()->IsAnyMouseDown(); } + inline ImVec2 GetMousePos() { return imgui_function_table_instance()->GetMousePos(); } + inline ImVec2 GetMousePosOnOpeningCurrentPopup() { return imgui_function_table_instance()->GetMousePosOnOpeningCurrentPopup(); } + inline bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold) { return imgui_function_table_instance()->IsMouseDragging(button, lock_threshold); } + inline ImVec2 GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold) { return imgui_function_table_instance()->GetMouseDragDelta(button, lock_threshold); } + inline void ResetMouseDragDelta(ImGuiMouseButton button) { imgui_function_table_instance()->ResetMouseDragDelta(button); } + inline ImGuiMouseCursor GetMouseCursor() { return imgui_function_table_instance()->GetMouseCursor(); } + inline void SetMouseCursor(ImGuiMouseCursor cursor_type) { imgui_function_table_instance()->SetMouseCursor(cursor_type); } + inline void SetNextFrameWantCaptureMouse(bool want_capture_mouse) { imgui_function_table_instance()->SetNextFrameWantCaptureMouse(want_capture_mouse); } + inline const char* GetClipboardText() { return imgui_function_table_instance()->GetClipboardText(); } + inline void SetClipboardText(const char* text) { imgui_function_table_instance()->SetClipboardText(text); } + inline void SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data) { imgui_function_table_instance()->SetAllocatorFunctions(alloc_func, free_func, user_data); } + inline void GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data) { imgui_function_table_instance()->GetAllocatorFunctions(p_alloc_func, p_free_func, p_user_data); } + inline void* MemAlloc(size_t size) { return imgui_function_table_instance()->MemAlloc(size); } + inline void MemFree(void* ptr) { imgui_function_table_instance()->MemFree(ptr); } + +} + +inline int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetInt(this, key, default_val); } +inline void ImGuiStorage::SetInt(ImGuiID key, int val) { imgui_function_table_instance()->ImGuiStorage_SetInt(this, key, val); } +inline bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetBool(this, key, default_val); } +inline void ImGuiStorage::SetBool(ImGuiID key, bool val) { imgui_function_table_instance()->ImGuiStorage_SetBool(this, key, val); } +inline float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { return imgui_function_table_instance()->ImGuiStorage_GetFloat(this, key, default_val); } +inline void ImGuiStorage::SetFloat(ImGuiID key, float val) { imgui_function_table_instance()->ImGuiStorage_SetFloat(this, key, val); } +inline void* ImGuiStorage::GetVoidPtr(ImGuiID key) const { return imgui_function_table_instance()->ImGuiStorage_GetVoidPtr(this, key); } +inline void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { imgui_function_table_instance()->ImGuiStorage_SetVoidPtr(this, key, val); } +inline int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) { return imgui_function_table_instance()->ImGuiStorage_GetIntRef(this, key, default_val); } +inline bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) { return imgui_function_table_instance()->ImGuiStorage_GetBoolRef(this, key, default_val); } +inline float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) { return imgui_function_table_instance()->ImGuiStorage_GetFloatRef(this, key, default_val); } +inline void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) { return imgui_function_table_instance()->ImGuiStorage_GetVoidPtrRef(this, key, default_val); } +inline void ImGuiStorage::SetAllInt(int val) { imgui_function_table_instance()->ImGuiStorage_SetAllInt(this, val); } +inline void ImGuiStorage::BuildSortByKey() { imgui_function_table_instance()->ImGuiStorage_BuildSortByKey(this); } +inline ImGuiListClipper::ImGuiListClipper() { imgui_function_table_instance()->ConstructImGuiListClipper(this); } +inline ImGuiListClipper::~ImGuiListClipper() { imgui_function_table_instance()->DestructImGuiListClipper(this); } +inline void ImGuiListClipper::Begin(int items_count, float items_height) { imgui_function_table_instance()->ImGuiListClipper_Begin(this, items_count, items_height); } +inline void ImGuiListClipper::End() { imgui_function_table_instance()->ImGuiListClipper_End(this); } +inline bool ImGuiListClipper::Step() { return imgui_function_table_instance()->ImGuiListClipper_Step(this); } +inline void ImGuiListClipper::IncludeRangeByIndices(int item_begin, int item_end) { imgui_function_table_instance()->ImGuiListClipper_IncludeRangeByIndices(this, item_begin, item_end); } +inline void ImDrawList::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { imgui_function_table_instance()->ImDrawList_PushClipRect(this, clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); } +inline void ImDrawList::PushClipRectFullScreen() { imgui_function_table_instance()->ImDrawList_PushClipRectFullScreen(this); } +inline void ImDrawList::PopClipRect() { imgui_function_table_instance()->ImDrawList_PopClipRect(this); } +inline void ImDrawList::PushTextureID(ImTextureID texture_id) { imgui_function_table_instance()->ImDrawList_PushTextureID(this, texture_id); } +inline void ImDrawList::PopTextureID() { imgui_function_table_instance()->ImDrawList_PopTextureID(this); } +inline void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddLine(this, p1, p2, col, thickness); } +inline void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) { imgui_function_table_instance()->ImDrawList_AddRect(this, p_min, p_max, col, rounding, flags, thickness); } +inline void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_AddRectFilled(this, p_min, p_max, col, rounding, flags); } +inline void ImDrawList::AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) { imgui_function_table_instance()->ImDrawList_AddRectFilledMultiColor(this, p_min, p_max, col_upr_left, col_upr_right, col_bot_right, col_bot_left); } +inline void ImDrawList::AddQuad(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddQuad(this, p1, p2, p3, p4, col, thickness); } +inline void ImDrawList::AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddQuadFilled(this, p1, p2, p3, p4, col); } +inline void ImDrawList::AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness) { imgui_function_table_instance()->ImDrawList_AddTriangle(this, p1, p2, p3, col, thickness); } +inline void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddTriangleFilled(this, p1, p2, p3, col); } +inline void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) { imgui_function_table_instance()->ImDrawList_AddCircle(this, center, radius, col, num_segments, thickness); } +inline void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) { imgui_function_table_instance()->ImDrawList_AddCircleFilled(this, center, radius, col, num_segments); } +inline void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) { imgui_function_table_instance()->ImDrawList_AddNgon(this, center, radius, col, num_segments, thickness); } +inline void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) { imgui_function_table_instance()->ImDrawList_AddNgonFilled(this, center, radius, col, num_segments); } +inline void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { imgui_function_table_instance()->ImDrawList_AddText(this, pos, col, text_begin, text_end); } +inline void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) { imgui_function_table_instance()->ImDrawList_AddText2(this, font, font_size, pos, col, text_begin, text_end, wrap_width, cpu_fine_clip_rect); } +inline void ImDrawList::AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness) { imgui_function_table_instance()->ImDrawList_AddPolyline(this, points, num_points, col, flags, thickness); } +inline void ImDrawList::AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddConvexPolyFilled(this, points, num_points, col); } +inline void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) { imgui_function_table_instance()->ImDrawList_AddBezierCubic(this, p1, p2, p3, p4, col, thickness, num_segments); } +inline void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments) { imgui_function_table_instance()->ImDrawList_AddBezierQuadratic(this, p1, p2, p3, col, thickness, num_segments); } +inline void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddImage(this, user_texture_id, p_min, p_max, uv_min, uv_max, col); } +inline void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& uv1, const ImVec2& uv2, const ImVec2& uv3, const ImVec2& uv4, ImU32 col) { imgui_function_table_instance()->ImDrawList_AddImageQuad(this, user_texture_id, p1, p2, p3, p4, uv1, uv2, uv3, uv4, col); } +inline void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_AddImageRounded(this, user_texture_id, p_min, p_max, uv_min, uv_max, col, rounding, flags); } +inline void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) { imgui_function_table_instance()->ImDrawList_PathArcTo(this, center, radius, a_min, a_max, num_segments); } +inline void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12) { imgui_function_table_instance()->ImDrawList_PathArcToFast(this, center, radius, a_min_of_12, a_max_of_12); } +inline void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) { imgui_function_table_instance()->ImDrawList_PathBezierCubicCurveTo(this, p2, p3, p4, num_segments); } +inline void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments) { imgui_function_table_instance()->ImDrawList_PathBezierQuadraticCurveTo(this, p2, p3, num_segments); } +inline void ImDrawList::PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding, ImDrawFlags flags) { imgui_function_table_instance()->ImDrawList_PathRect(this, rect_min, rect_max, rounding, flags); } +inline void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { imgui_function_table_instance()->ImDrawList_AddCallback(this, callback, callback_data); } +inline void ImDrawList::AddDrawCmd() { imgui_function_table_instance()->ImDrawList_AddDrawCmd(this); } +inline ImDrawList* ImDrawList::CloneOutput() const { return imgui_function_table_instance()->ImDrawList_CloneOutput(this); } +inline void ImDrawList::PrimReserve(int idx_count, int vtx_count) { imgui_function_table_instance()->ImDrawList_PrimReserve(this, idx_count, vtx_count); } +inline void ImDrawList::PrimUnreserve(int idx_count, int vtx_count) { imgui_function_table_instance()->ImDrawList_PrimUnreserve(this, idx_count, vtx_count); } +inline void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimRect(this, a, b, col); } +inline void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimRectUV(this, a, b, uv_a, uv_b, col); } +inline void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) { imgui_function_table_instance()->ImDrawList_PrimQuadUV(this, a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); } +inline ImFont::ImFont() { imgui_function_table_instance()->ConstructImFont(this); } +inline ImFont::~ImFont() { imgui_function_table_instance()->DestructImFont(this); } +inline const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const { return imgui_function_table_instance()->ImFont_FindGlyph(this, c); } +inline const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const { return imgui_function_table_instance()->ImFont_FindGlyphNoFallback(this, c); } +inline ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const { return imgui_function_table_instance()->ImFont_CalcTextSizeA(this, size, max_width, wrap_width, text_begin, text_end, remaining); } +inline const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const { return imgui_function_table_instance()->ImFont_CalcWordWrapPositionA(this, scale, text, text_end, wrap_width); } +inline void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const { imgui_function_table_instance()->ImFont_RenderChar(this, draw_list, size, pos, col, c); } +inline void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const { imgui_function_table_instance()->ImFont_RenderText(this, draw_list, size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip); } + + +#endif + +#endif