commit 781b062fcaadc411222f887ae2ea75d66b873fb3 Author: Nico de Poel Date: Mon Mar 10 15:36:04 2025 +0100 Created initial skeleton of FSR3 native render plugin, with all type declarations and stubbed-out public interface functions. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..652e763 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.user +.vs/ +FSR3UnityPlugin/x64/ +x64/ diff --git a/FSR3UnityPlugin.cpp b/FSR3UnityPlugin.cpp new file mode 100644 index 0000000..89ecd97 --- /dev/null +++ b/FSR3UnityPlugin.cpp @@ -0,0 +1,172 @@ +#include + +#include "UnityPluginAPI/IUnityInterface.h" +#include "UnityPluginAPI/IUnityLog.h" +#include "UnityPluginAPI/IUnityGraphics.h" +#include "UnityPluginAPI/IUnityRenderingExtensions.h" +//#include "UnityPluginAPI/IUnityGraphicsD3D12.h" + +#include "FSR3UnityTypes.h" + +static const int32_t BaseEventId = 0; + +static IUnityInterfaces* s_UnityInterfaces = nullptr; +static IUnityLog* s_Log = nullptr; +static IUnityGraphics* s_Graphics = nullptr; +static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; + +static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType); +static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data); +static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data); + +// Unity plugin load event +extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces) +{ + s_UnityInterfaces = unityInterfaces; + s_Log = unityInterfaces->Get(); + s_Graphics = unityInterfaces->Get(); + + s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent); + + // Run OnGraphicsDeviceEvent(initialize) manually on plugin load + // to not miss the event in case the graphics device is already initialized + OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize); +} + +// Unity plugin unload event +extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload() +{ + s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent); +} + +static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType) +{ + switch (eventType) + { + case kUnityGfxDeviceEventInitialize: + { + s_RendererType = s_Graphics->GetRenderer(); + //TODO: user initialization code on graphics device initialization. For example, D3D11 resource creation. + break; + } + case kUnityGfxDeviceEventShutdown: + { + s_RendererType = kUnityGfxRendererNull; + //TODO: user graphics API code to call on graphics device shutdown. + break; + } + case kUnityGfxDeviceEventBeforeReset: + { + //TODO: user graphics API code to call before graphics device reset. + break; + } + case kUnityGfxDeviceEventAfterReset: + { + //TODO: user graphics API code to call after graphics device reset. + break; + } + }; +} + +extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_InitApi() +{ + // TODO: implement + return false; +} + +extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_ShutdownApi() +{ + // TODO: implement +} + +extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetDeviceVersion() +{ + return 0x0u; +} + +extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderEventCallback() +{ + return OnRenderEventAndData; +} + +extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetSetTextureEventCallback() +{ + return OnSetTextureEvent; +} + +extern "C" uint32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_CreateFeatureSlot() +{ + // TODO: thread-safe allocation of slot + return 0u; +} + +// TODO: use FSR2Quality enum for qualityMode +extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetRenderResolutionFromQualityMode(FSR3Quality qualityMode, uint32_t displayWidth, uint32_t displayHeight, uint32_t* renderWidth, uint32_t* renderHeight) +{ + // TODO: implement + return false; +} + +// TODO: use FSR2Quality enum for qualityMode +extern "C" float UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetUpscaleRatioFromQualityMode(FSR3Quality qualityMode) +{ + // TODO: implement + return 1.0f; +} + +extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API AMDUP_GetBaseEventId() +{ + return BaseEventId; +} + +// Plugin function to handle a specific rendering event +static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data) +{ + // User rendering code + switch (eventID) + { + case BaseEventId + FSR3PluginEvent::eDestroyFeature: + { + // TODO: thread-safe freeing of slot (data = feature slot int64_t, cast as pointer) + uint32_t featureSlot = (uint32_t)(int64_t)data; + break; + } + case BaseEventId + FSR3PluginEvent::eExecute: + { + auto* params = (FSR3CommandExecutionData*)data; + break; + } + case BaseEventId + FSR3PluginEvent::ePostExecute: + { + auto* params = (FSR3CommandExecutionData*)data; + break; + } + case BaseEventId + FSR3PluginEvent::eInit: + { + auto* params = (FSR3CommandInitializationData*)data; + break; + } + } +} + +static void UNITY_INTERFACE_API OnSetTextureEvent(int eventID, void* data) +{ + // TODO userData field in UnityRenderingExtTextureUpdateParamsV2 is an encoded value: (featureId & (int) ushort.MaxValue) << 16 | (textureSlot & (int) short.MaxValue) << 1 | (clearTextureTable ? 1 : 0); + auto* params = (UnityRenderingExtTextureUpdateParamsV2*)data; + + // TODO: featureId => featureSlot + // TODO: textureSlot => FSR3Textures enum (could just use as numeric index to calculate a pointer offset) + + // User rendering code + switch (eventID) + { + case kUnityRenderingExtEventUpdateTextureBeginV2: + { + break; + } + case kUnityRenderingExtEventUpdateTextureEndV2: + { + break; + } + } +} diff --git a/FSR3UnityPlugin.sln b/FSR3UnityPlugin.sln new file mode 100644 index 0000000..fe1b53d --- /dev/null +++ b/FSR3UnityPlugin.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FSR3UnityPlugin", "FSR3UnityPlugin.vcxproj", "{505A5886-66BC-4210-B4E8-1301CFB75E74}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Debug|x64.ActiveCfg = Debug|x64 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Debug|x64.Build.0 = Debug|x64 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Debug|x86.ActiveCfg = Debug|Win32 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Debug|x86.Build.0 = Debug|Win32 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Release|x64.ActiveCfg = Release|x64 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Release|x64.Build.0 = Release|x64 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Release|x86.ActiveCfg = Release|Win32 + {505A5886-66BC-4210-B4E8-1301CFB75E74}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF6223E3-CF48-454B-9416-28A20C03A8FB} + EndGlobalSection +EndGlobal diff --git a/FSR3UnityPlugin.vcxproj b/FSR3UnityPlugin.vcxproj new file mode 100644 index 0000000..06c8bc0 --- /dev/null +++ b/FSR3UnityPlugin.vcxproj @@ -0,0 +1,156 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {505a5886-66bc-4210-b4e8-1301cfb75e74} + FSR3UnityPlugin + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + AMDUnityPlugin + + + AMDUnityPlugin + + + + Level3 + true + WIN32;_DEBUG;FSR3UNITYPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;FSR3UNITYPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;FSR3UNITYPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + false + + + + + Level3 + true + true + true + NDEBUG;FSR3UNITYPLUGIN_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + + + Windows + true + true + true + false + + + + + + + + + + + + \ No newline at end of file diff --git a/FSR3UnityPlugin.vcxproj.filters b/FSR3UnityPlugin.vcxproj.filters new file mode 100644 index 0000000..5268b4b --- /dev/null +++ b/FSR3UnityPlugin.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/FSR3UnityTypes.h b/FSR3UnityTypes.h new file mode 100644 index 0000000..60d9426 --- /dev/null +++ b/FSR3UnityTypes.h @@ -0,0 +1,58 @@ +#pragma once + +enum FSR3PluginEvent : int32_t +{ + eDestroyFeature, + eExecute, + ePostExecute, + eInit +}; + +enum FSR3Quality: int32_t +{ + qQuality, + qBalanced, + qPerformance, + qUltraPerformance +}; + +enum FSR3Textures: int32_t +{ + tColorInput, + tColorOutput, + tDepth, + tMotionVectors, + tTransparencyMask, + tExposureTexture, + tReactiveMask, + tBiasColorMask, +}; + +struct FSR3CommandInitializationData +{ + uint32_t maxRenderSizeWidth; + uint32_t maxRenderSizeHeight; + uint32_t displaySizeWidth; + uint32_t displaySizeHeight; + int32_t flags; + uint32_t featureSlot; +}; + +struct FSR3CommandExecutionData +{ + float jitterOffsetX; + float jitterOffsetY; + float MVScaleX; + float MVScaleY; + uint32_t renderSizeWidth; + uint32_t renderSizeHeight; + int32_t enableSharpening; + float sharpness; + float frameTimeDelta; + float preExposure; + int32_t reset; + float cameraNear; + float cameraFar; + float cameraFovAngleVertical; + uint32_t featureSlot; +}; diff --git a/UnityPluginAPI/IUnityGraphics.h b/UnityPluginAPI/IUnityGraphics.h new file mode 100644 index 0000000..71dea56 --- /dev/null +++ b/UnityPluginAPI/IUnityGraphics.h @@ -0,0 +1,62 @@ +// Unity Native Plugin API copyright © 2015 Unity Technologies ApS +// +// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +// +// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions. + +#pragma once +#include "IUnityInterface.h" + +// Has to match the GfxDeviceRenderer enum +typedef enum UnityGfxRenderer +{ + //kUnityGfxRendererOpenGL = 0, // Legacy OpenGL, removed + //kUnityGfxRendererD3D9 = 1, // Direct3D 9, removed + kUnityGfxRendererD3D11 = 2, // Direct3D 11 + kUnityGfxRendererNull = 4, // "null" device (used in batch mode) + kUnityGfxRendererOpenGLES20 = 8, // OpenGL ES 2.0 + kUnityGfxRendererOpenGLES30 = 11, // OpenGL ES 3.0 + //kUnityGfxRendererGXM = 12, // PlayStation Vita, removed + kUnityGfxRendererPS4 = 13, // PlayStation 4 + kUnityGfxRendererXboxOne = 14, // Xbox One + kUnityGfxRendererMetal = 16, // iOS Metal + kUnityGfxRendererOpenGLCore = 17, // OpenGL core + kUnityGfxRendererD3D12 = 18, // Direct3D 12 + kUnityGfxRendererVulkan = 21, // Vulkan + kUnityGfxRendererNvn = 22, // Nintendo Switch NVN API + kUnityGfxRendererXboxOneD3D12 = 23, // MS XboxOne Direct3D 12 + kUnityGfxRendererGameCoreXboxOne = 24, // GameCore Xbox One + kUnityGfxRendererGameCoreXboxSeries = 25, // GameCore XboxSeries + kUnityGfxRendererPS5 = 26, // PS5 + kUnityGfxRendererPS5NGGC = 27 // PS5 NGGC +} UnityGfxRenderer; + +typedef enum UnityGfxDeviceEventType +{ + kUnityGfxDeviceEventInitialize = 0, + kUnityGfxDeviceEventShutdown = 1, + kUnityGfxDeviceEventBeforeReset = 2, + kUnityGfxDeviceEventAfterReset = 3, +} UnityGfxDeviceEventType; + +typedef void (UNITY_INTERFACE_API * IUnityGraphicsDeviceEventCallback)(UnityGfxDeviceEventType eventType); + +// Should only be used on the rendering thread unless noted otherwise. +UNITY_DECLARE_INTERFACE(IUnityGraphics) +{ + UnityGfxRenderer(UNITY_INTERFACE_API * GetRenderer)(); // Thread safe + + // This callback will be called when graphics device is created, destroyed, reset, etc. + // It is possible to miss the kUnityGfxDeviceEventInitialize event in case plugin is loaded at a later time, + // when the graphics device is already created. + void(UNITY_INTERFACE_API * RegisterDeviceEventCallback)(IUnityGraphicsDeviceEventCallback callback); + void(UNITY_INTERFACE_API * UnregisterDeviceEventCallback)(IUnityGraphicsDeviceEventCallback callback); + int(UNITY_INTERFACE_API * ReserveEventIDRange)(int count); // reserves 'count' event IDs. Plugins should use the result as a base index when issuing events back and forth to avoid event id clashes. +}; +UNITY_REGISTER_INTERFACE_GUID(0x7CBA0A9CA4DDB544ULL, 0x8C5AD4926EB17B11ULL, IUnityGraphics) + + +// Certain Unity APIs (GL.IssuePluginEvent, CommandBuffer.IssuePluginEvent) can callback into native plugins. +// Provide them with an address to a function of this signature. +typedef void (UNITY_INTERFACE_API * UnityRenderingEvent)(int eventId); +typedef void (UNITY_INTERFACE_API * UnityRenderingEventAndData)(int eventId, void* data); diff --git a/UnityPluginAPI/IUnityGraphicsD3D12.h b/UnityPluginAPI/IUnityGraphicsD3D12.h new file mode 100644 index 0000000..3dfdccf --- /dev/null +++ b/UnityPluginAPI/IUnityGraphicsD3D12.h @@ -0,0 +1,217 @@ +// Unity Native Plugin API copyright © 2015 Unity Technologies ApS +// +// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +// +// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions. + +#pragma once +#include "IUnityInterface.h" +#ifndef __cplusplus + #include +#endif + +struct RenderSurfaceBase; +typedef struct RenderSurfaceBase* UnityRenderBuffer; + +typedef struct UnityGraphicsD3D12ResourceState UnityGraphicsD3D12ResourceState; +struct UnityGraphicsD3D12ResourceState +{ + ID3D12Resource* resource; // Resource to barrier. + D3D12_RESOURCE_STATES expected; // Expected resource state before this command list is executed. + D3D12_RESOURCE_STATES current; // State this resource will be in after this command list is executed. +}; + +struct UnityGraphicsD3D12RecordingState +{ + ID3D12GraphicsCommandList* commandList; // D3D12 command list that is currently recorded by Unity +}; + +enum UnityD3D12GraphicsQueueAccess +{ + // No queue acccess, no work must be submitted to UnityD3D12Instance::graphicsQueue from the plugin event callback + kUnityD3D12GraphicsQueueAccess_DontCare, + + // Make sure that Unity worker threads don't access the D3D12 graphics queue + // This disables access to the current Unity command buffer + kUnityD3D12GraphicsQueueAccess_Allow, +}; + +enum UnityD3D12EventConfigFlagBits +{ + kUnityD3D12EventConfigFlag_EnsurePreviousFrameSubmission = (1 << 0), // default: (NOT SUPPORTED) + kUnityD3D12EventConfigFlag_FlushCommandBuffers = (1 << 1), // submit existing command buffers, default: not set + kUnityD3D12EventConfigFlag_SyncWorkerThreads = (1 << 2), // wait for worker threads to finish, default: not set + kUnityD3D12EventConfigFlag_ModifiesCommandBuffersState = (1 << 3), // should be set when descriptor set bindings, vertex buffer bindings, etc are changed (default: set) +}; + +struct UnityD3D12PluginEventConfig +{ + UnityD3D12GraphicsQueueAccess graphicsQueueAccess; + UINT32 flags; // UnityD3D12EventConfigFlagBits to be used when invoking a native plugin + bool ensureActiveRenderTextureIsBound; // If true, the actively bound render texture will be bound prior the execution of the native plugin method. +}; + +typedef struct UnityGraphicsD3D12PhysicalVideoMemoryControlValues UnityGraphicsD3D12PhysicalVideoMemoryControlValues; +struct UnityGraphicsD3D12PhysicalVideoMemoryControlValues // all absolute values in bytes +{ + UINT64 reservation; // Minimum required physical memory for an application [default = 64MB]. + UINT64 systemMemoryThreshold; // If free physical video memory drops below this threshold, resources will be allocated in system memory. [default = 64MB] + UINT64 residencyHysteresisThreshold; // Minimum free physical video memory needed to start bringing evicted resources back after shrunken video memory budget expands again. [default = 128MB] + float nonEvictableRelativeThreshold; // The relative proportion of the video memory budget that must be kept available for non-evictable resources. [default = 0.25] +}; + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v7) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + IDXGISwapChain* (UNITY_INTERFACE_API * GetSwapChain)(); + UINT32(UNITY_INTERFACE_API * GetSyncInterval)(); + UINT(UNITY_INTERFACE_API * GetPresentFlags)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); + + void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); + + ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); + + ID3D12Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer rb); + ID3D12Resource* (UNITY_INTERFACE_API * TextureFromNativeTexture)(UnityTextureID texture); + + // Change the precondition for a specific user-defined event + // Should be called during initialization + void(UNITY_INTERFACE_API * ConfigureEvent)(int eventID, const UnityD3D12PluginEventConfig * pluginEventConfig); + + bool(UNITY_INTERFACE_API * CommandRecordingState)(UnityGraphicsD3D12RecordingState * outCommandRecordingState); +}; +UNITY_REGISTER_INTERFACE_GUID(0x4624B0DA41B64AACULL, 0x915AABCB9BC3F0D3ULL, IUnityGraphicsD3D12v7) + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v6) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); + + void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); + + ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); + + ID3D12Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer rb); + ID3D12Resource* (UNITY_INTERFACE_API * TextureFromNativeTexture)(UnityTextureID texture); + + // Change the precondition for a specific user-defined event + // Should be called during initialization + void(UNITY_INTERFACE_API * ConfigureEvent)(int eventID, const UnityD3D12PluginEventConfig * pluginEventConfig); + + bool(UNITY_INTERFACE_API * CommandRecordingState)(UnityGraphicsD3D12RecordingState* outCommandRecordingState); +}; +UNITY_REGISTER_INTERFACE_GUID(0xA396DCE58CAC4D78ULL, 0xAFDD9B281F20B840ULL, IUnityGraphicsD3D12v6) + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v5) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); + + void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); + + ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); + + ID3D12Resource* (UNITY_INTERFACE_API * TextureFromRenderBuffer)(UnityRenderBuffer rb); +}; +UNITY_REGISTER_INTERFACE_GUID(0xF5C8D8A37D37BC42ULL, 0xB02DFE93B5064A27ULL, IUnityGraphicsD3D12v5) + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v4) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); + + void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); + + ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); +}; +UNITY_REGISTER_INTERFACE_GUID(0X498FFCC13EC94006ULL, 0XB18F8B0FF67778C8ULL, IUnityGraphicsD3D12v4) + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v3) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); + + void(UNITY_INTERFACE_API * SetPhysicalVideoMemoryControlValues)(const UnityGraphicsD3D12PhysicalVideoMemoryControlValues * memInfo); +}; +UNITY_REGISTER_INTERFACE_GUID(0x57C3FAFE59E5E843ULL, 0xBF4F5998474BB600ULL, IUnityGraphicsD3D12v3) + +// Should only be used on the rendering/submission thread. +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v2) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Executes a given command list on a worker thread. The command list type must be D3D12_COMMAND_LIST_TYPE_DIRECT. + // [Optional] Declares expected and post-execution resource states. + // Returns the fence value. The value will be set once the current frame completes or the GPU is flushed. + UINT64(UNITY_INTERFACE_API * ExecuteCommandList)(ID3D12GraphicsCommandList * commandList, int stateCount, UnityGraphicsD3D12ResourceState * states); +}; +UNITY_REGISTER_INTERFACE_GUID(0xEC39D2F18446C745ULL, 0xB1A2626641D6B11FULL, IUnityGraphicsD3D12v2) + + +// Obsolete +UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12) +{ + ID3D12Device* (UNITY_INTERFACE_API * GetDevice)(); + ID3D12CommandQueue* (UNITY_INTERFACE_API * GetCommandQueue)(); + + ID3D12Fence* (UNITY_INTERFACE_API * GetFrameFence)(); + // Returns the value set on the frame fence once the current frame completes or the GPU is flushed + UINT64(UNITY_INTERFACE_API * GetNextFrameFenceValue)(); + + // Returns the state a resource will be in after the last command list is executed + bool(UNITY_INTERFACE_API * GetResourceState)(ID3D12Resource * resource, D3D12_RESOURCE_STATES * outState); + // Specifies the state a resource will be in after a plugin command list with resource barriers is executed + void(UNITY_INTERFACE_API * SetResourceState)(ID3D12Resource * resource, D3D12_RESOURCE_STATES state); +}; +UNITY_REGISTER_INTERFACE_GUID(0xEF4CEC88A45F4C4CULL, 0xBD295B6F2A38D9DEULL, IUnityGraphicsD3D12) diff --git a/UnityPluginAPI/IUnityInterface.h b/UnityPluginAPI/IUnityInterface.h new file mode 100644 index 0000000..ab713ec --- /dev/null +++ b/UnityPluginAPI/IUnityInterface.h @@ -0,0 +1,206 @@ +// Unity Native Plugin API copyright © 2015 Unity Technologies ApS +// +// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +// +// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions. + +#pragma once + +// Unity native plugin API +// Compatible with C99 + +#if defined(__CYGWIN32__) + #define UNITY_INTERFACE_API __stdcall + #define UNITY_INTERFACE_EXPORT __declspec(dllexport) +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(WINAPI_FAMILY) + #define UNITY_INTERFACE_API __stdcall + #define UNITY_INTERFACE_EXPORT __declspec(dllexport) +#elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || defined(LUMIN) + #define UNITY_INTERFACE_API + #define UNITY_INTERFACE_EXPORT __attribute__ ((visibility ("default"))) +#else + #define UNITY_INTERFACE_API + #define UNITY_INTERFACE_EXPORT +#endif + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IUnityInterface is a registry of interfaces we choose to expose to plugins. +// +// USAGE: +// --------- +// To retrieve an interface a user can do the following from a plugin, assuming they have the header file for the interface: +// +// IMyInterface * ptr = registry->Get(); +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Unity Interface GUID +// Ensures global uniqueness. +// +// Template specialization is used to produce a means of looking up a GUID from its interface type at compile time. +// The net result should compile down to passing around the GUID. +// +// UNITY_REGISTER_INTERFACE_GUID should be placed in the header file of any interface definition outside of all namespaces. +// The interface structure and the registration GUID are all that is required to expose the interface to other systems. +struct UnityInterfaceGUID +{ +#ifdef __cplusplus + UnityInterfaceGUID(unsigned long long high, unsigned long long low) + : m_GUIDHigh(high) + , m_GUIDLow(low) + { + } + + UnityInterfaceGUID(const UnityInterfaceGUID& other) + { + m_GUIDHigh = other.m_GUIDHigh; + m_GUIDLow = other.m_GUIDLow; + } + + UnityInterfaceGUID& operator=(const UnityInterfaceGUID& other) + { + m_GUIDHigh = other.m_GUIDHigh; + m_GUIDLow = other.m_GUIDLow; + return *this; + } + + bool Equals(const UnityInterfaceGUID& other) const { return m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow == other.m_GUIDLow; } + bool LessThan(const UnityInterfaceGUID& other) const { return m_GUIDHigh < other.m_GUIDHigh || (m_GUIDHigh == other.m_GUIDHigh && m_GUIDLow < other.m_GUIDLow); } +#endif + unsigned long long m_GUIDHigh; + unsigned long long m_GUIDLow; +}; +#ifdef __cplusplus +inline bool operator==(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.Equals(right); } +inline bool operator!=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !left.Equals(right); } +inline bool operator<(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return left.LessThan(right); } +inline bool operator>(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return right.LessThan(left); } +inline bool operator>=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator<(left, right); } +inline bool operator<=(const UnityInterfaceGUID& left, const UnityInterfaceGUID& right) { return !operator>(left, right); } +#else +typedef struct UnityInterfaceGUID UnityInterfaceGUID; +#endif + + +#ifdef __cplusplus + #define UNITY_DECLARE_INTERFACE(NAME) \ + struct NAME : IUnityInterface + +// Generic version of GetUnityInterfaceGUID to allow us to specialize it +// per interface below. The generic version has no actual implementation +// on purpose. +// +// If you get errors about return values related to this method then +// you have forgotten to include UNITY_REGISTER_INTERFACE_GUID with +// your interface, or it is not visible at some point when you are +// trying to retrieve or add an interface. +template +inline const UnityInterfaceGUID GetUnityInterfaceGUID(); + +// This is the macro you provide in your public interface header +// outside of a namespace to allow us to map between type and GUID +// without the user having to worry about it when attempting to +// add or retrieve and interface from the registry. + #define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \ + template<> \ + inline const UnityInterfaceGUID GetUnityInterfaceGUID() \ + { \ + return UnityInterfaceGUID(HASHH,HASHL); \ + } + +// Same as UNITY_REGISTER_INTERFACE_GUID but allows the interface to live in +// a particular namespace. As long as the namespace is visible at the time you call +// GetUnityInterfaceGUID< INTERFACETYPE >() or you explicitly qualify it in the template +// calls this will work fine, only the macro here needs to have the additional parameter + #define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE) \ + const UnityInterfaceGUID TYPE##_GUID(HASHH, HASHL); \ + template<> \ + inline const UnityInterfaceGUID GetUnityInterfaceGUID< NAMESPACE :: TYPE >() \ + { \ + return UnityInterfaceGUID(HASHH,HASHL); \ + } + +// These macros allow for C compatibility in user code. + #define UNITY_GET_INTERFACE_GUID(TYPE) GetUnityInterfaceGUID< TYPE >() + + +#else + #define UNITY_DECLARE_INTERFACE(NAME) \ + typedef struct NAME NAME; \ + struct NAME + +// NOTE: This has the downside that one some compilers it will not get stripped from all compilation units that +// can see a header containing this constant. However, it's only for C compatibility and thus should have +// minimal impact. + #define UNITY_REGISTER_INTERFACE_GUID(HASHH, HASHL, TYPE) \ + const UnityInterfaceGUID TYPE##_GUID = {HASHH, HASHL}; + +// In general namespaces are going to be a problem for C code any interfaces we expose in a namespace are +// not going to be usable from C. + #define UNITY_REGISTER_INTERFACE_GUID_IN_NAMESPACE(HASHH, HASHL, TYPE, NAMESPACE) + +// These macros allow for C compatibility in user code. + #define UNITY_GET_INTERFACE_GUID(TYPE) TYPE##_GUID +#endif + +// Using this in user code rather than INTERFACES->Get() will be C compatible for those places in plugins where +// this may be needed. Unity code itself does not need this. +#define UNITY_GET_INTERFACE(INTERFACES, TYPE) (TYPE*)INTERFACES->GetInterfaceSplit (UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDHigh, UNITY_GET_INTERFACE_GUID(TYPE).m_GUIDLow); + + +#ifdef __cplusplus +struct IUnityInterface +{ +}; +#else +typedef void IUnityInterface; +#endif + + +typedef struct IUnityInterfaces +{ + // Returns an interface matching the guid. + // Returns nullptr if the given interface is unavailable in the active Unity runtime. + IUnityInterface* (UNITY_INTERFACE_API * GetInterface)(UnityInterfaceGUID guid); + + // Registers a new interface. + void(UNITY_INTERFACE_API * RegisterInterface)(UnityInterfaceGUID guid, IUnityInterface * ptr); + + // Split APIs for C + IUnityInterface* (UNITY_INTERFACE_API * GetInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow); + void(UNITY_INTERFACE_API * RegisterInterfaceSplit)(unsigned long long guidHigh, unsigned long long guidLow, IUnityInterface * ptr); + +#ifdef __cplusplus + // Helper for GetInterface. + template + INTERFACE* Get() + { + return static_cast(GetInterface(GetUnityInterfaceGUID())); + } + + // Helper for RegisterInterface. + template + void Register(IUnityInterface* ptr) + { + RegisterInterface(GetUnityInterfaceGUID(), ptr); + } + +#endif +} IUnityInterfaces; + + +#ifdef __cplusplus +extern "C" { +#endif + +// If exported by a plugin, this function will be called when the plugin is loaded. +void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces); +// If exported by a plugin, this function will be called when the plugin is about to be unloaded. +void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload(); + +#ifdef __cplusplus +} +#endif + +struct RenderSurfaceBase; +typedef struct RenderSurfaceBase* UnityRenderBuffer; +typedef unsigned int UnityTextureID; diff --git a/UnityPluginAPI/IUnityLog.h b/UnityPluginAPI/IUnityLog.h new file mode 100644 index 0000000..c537585 --- /dev/null +++ b/UnityPluginAPI/IUnityLog.h @@ -0,0 +1,37 @@ +// Unity Native Plugin API copyright © 2015 Unity Technologies ApS +// +// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +// +// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions. + +#pragma once +#include "IUnityInterface.h" + +/// The type of the log message +enum UnityLogType +{ + /// UnityLogType used for Errors. + kUnityLogTypeError = 0, + /// UnityLogType used for Warnings. + kUnityLogTypeWarning = 2, + /// UnityLogType used for regular log messages. + kUnityLogTypeLog = 3, + /// UnityLogType used for Exceptions. + kUnityLogTypeException = 4, +}; + +#define UNITY_WRAP_CODE(CODE_) do { CODE_; } while (0) +#define UNITY_LOG(PTR_, MSG_) UNITY_WRAP_CODE((PTR_)->Log(kUnityLogTypeLog, MSG_, __FILE__, __LINE__)) +#define UNITY_LOG_WARNING(PTR_, MSG_) UNITY_WRAP_CODE((PTR_)->Log(kUnityLogTypeWarning, MSG_, __FILE__, __LINE__)) +#define UNITY_LOG_ERROR(PTR_, MSG_) UNITY_WRAP_CODE((PTR_)->Log(kUnityLogTypeError, MSG_, __FILE__, __LINE__)) + +UNITY_DECLARE_INTERFACE(IUnityLog) +{ + // Writes information message to Unity log. + // \param type type log channel type which defines importance of the message. + // \param message UTF-8 null terminated string. + // \param fileName UTF-8 null terminated string with file name of the point where message is generated. + // \param fileLine integer file line number of the point where message is generated. + void(UNITY_INTERFACE_API * Log)(UnityLogType type, const char* message, const char *fileName, const int fileLine); +}; +UNITY_REGISTER_INTERFACE_GUID(0x9E7507fA5B444D5DULL, 0x92FB979515EA83FCULL, IUnityLog) diff --git a/UnityPluginAPI/IUnityRenderingExtensions.h b/UnityPluginAPI/IUnityRenderingExtensions.h new file mode 100644 index 0000000..fe3b515 --- /dev/null +++ b/UnityPluginAPI/IUnityRenderingExtensions.h @@ -0,0 +1,378 @@ +// Unity Native Plugin API copyright © 2015 Unity Technologies ApS +// +// Licensed under the Unity Companion License for Unity - dependent projects--see[Unity Companion License](http://www.unity3d.com/legal/licenses/Unity_Companion_License). +// +// Unless expressly provided otherwise, the Software under this license is made available strictly on an “AS IS” BASIS WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.Please review the license for details on these and other terms and conditions. + +#pragma once + + +#include "IUnityGraphics.h" + +/* + Low-level Native Plugin Rendering Extensions + ============================================ + + On top of the Low-level native plugin interface, Unity also supports low level rendering extensions that can receive callbacks when certain events happen. + This is mostly used to implement and control low-level rendering in your plugin and enable it to work with Unity’s multithreaded rendering. + + Due to the low-level nature of this extension the plugin might need to be preloaded before the devices get created. + Currently the convention is name-based namely the plugin name must be prefixed by “GfxPlugin”. Example: GfxPluginMyFancyNativePlugin. + + + // Native plugin code example + + enum PluginCustomCommands + { + kPluginCustomCommandDownscale = kUnityRenderingExtUserEventsStart, + kPluginCustomCommandUpscale, + + // insert your own events here + + kPluginCustomCommandCount + }; + + static IUnityInterfaces* s_UnityInterfaces = NULL; + + extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API + UnityPluginLoad(IUnityInterfaces* unityInterfaces) + { + // initialization code here... + } + + extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API + UnityRenderingExtEvent(UnityRenderingExtEventType event, void* data) + { + switch (event) + { + case kUnityRenderingExtEventBeforeDrawCall: + // do some stuff + break; + case kUnityRenderingExtEventAfterDrawCall: + // undo some stuff + break; + case kPluginCustomCommandDownscale: + // downscale some stuff + break; + case kPluginCustomCommandUpscale: + // upscale some stuff + break; + } + } + +*/ + + +// These events will be propagated to all plugins that implement void UnityRenderingExtEvent(UnityRenderingExtEventType event, void* data); + +typedef enum UnityRenderingExtEventType +{ + kUnityRenderingExtEventSetStereoTarget, // issued during SetStereoTarget and carrying the current 'eye' index as parameter + kUnityRenderingExtEventSetStereoEye, // issued during stereo rendering at the beginning of each eye's rendering loop. It carries the current 'eye' index as parameter + kUnityRenderingExtEventStereoRenderingDone, // issued after the rendering has finished + kUnityRenderingExtEventBeforeDrawCall, // issued during BeforeDrawCall and carrying UnityRenderingExtBeforeDrawCallParams as parameter + kUnityRenderingExtEventAfterDrawCall, // issued during AfterDrawCall. This event doesn't carry any parameters + kUnityRenderingExtEventCustomGrab, // issued during GrabIntoRenderTexture since we can't simply copy the resources + // when custom rendering is used - we need to let plugin handle this. It carries over + // a UnityRenderingExtCustomBlitParams params = { X, source, dest, 0, 0 } ( X means it's irrelevant ) + kUnityRenderingExtEventCustomBlit, // issued by plugin to insert custom blits. It carries over UnityRenderingExtCustomBlitParams as param. + kUnityRenderingExtEventUpdateTextureBegin, // Deprecated. + kUnityRenderingExtEventUpdateTextureEnd, // Deprecated. + kUnityRenderingExtEventUpdateTextureBeginV1 = kUnityRenderingExtEventUpdateTextureBegin, // Deprecated. Issued to update a texture. It carries over UnityRenderingExtTextureUpdateParamsV1 + kUnityRenderingExtEventUpdateTextureEndV1 = kUnityRenderingExtEventUpdateTextureEnd, // Deprecated. Issued to signal the plugin that the texture update has finished. It carries over the same UnityRenderingExtTextureUpdateParamsV1 as kUnityRenderingExtEventUpdateTextureBeginV1 + kUnityRenderingExtEventUpdateTextureBeginV2, // Issued to update a texture. It carries over UnityRenderingExtTextureUpdateParamsV2 + kUnityRenderingExtEventUpdateTextureEndV2, // Issued to signal the plugin that the texture update has finished. It carries over the same UnityRenderingExtTextureUpdateParamsV2 as kUnityRenderingExtEventUpdateTextureBeginV2 + + // keep this last + kUnityRenderingExtEventCount, + kUnityRenderingExtUserEventsStart = kUnityRenderingExtEventCount +} UnityRenderingExtEventType; + + +typedef enum UnityRenderingExtCustomBlitCommands +{ + kUnityRenderingExtCustomBlitVRFlush, // This event is mostly used in multi GPU configurations ( SLI, etc ) in order to allow the plugin to flush all GPU's targets + + // keep this last + kUnityRenderingExtCustomBlitCount, + kUnityRenderingExtUserCustomBlitStart = kUnityRenderingExtCustomBlitCount +} UnityRenderingExtCustomBlitCommands; + +/* + This will be propagated to all plugins implementing UnityRenderingExtQuery. +*/ +typedef enum UnityRenderingExtQueryType +{ + kUnityRenderingExtQueryOverrideViewport = 1 << 0, // The plugin handles setting up the viewport rects. Unity will skip its internal SetViewport calls + kUnityRenderingExtQueryOverrideScissor = 1 << 1, // The plugin handles setting up the scissor rects. Unity will skip its internal SetScissor calls + kUnityRenderingExtQueryOverrideVROcclussionMesh = 1 << 2, // The plugin handles its own VR occlusion mesh rendering. Unity will skip rendering its internal VR occlusion mask + kUnityRenderingExtQueryOverrideVRSinglePass = 1 << 3, // The plugin uses its own single pass stereo technique. Unity will only traverse and render the render node graph once. + // and it will clear the whole render target not just per-eye on demand. + kUnityRenderingExtQueryKeepOriginalDoubleWideWidth_DEPRECATED = 1 << 4, // Instructs unity to keep the original double wide width. By default unity will try and have a power-of-two width for mip-mapping requirements. + kUnityRenderingExtQueryRequestVRFlushCallback = 1 << 5, // Instructs unity to provide callbacks when the VR eye textures need flushing. Useful for multi GPU synchronization. + kUnityRenderingExtQueryOverridePresentFrame = 1 << 6, // The plugin handles it's own SwapChain Present. Unity will skip its internal Present calls +} UnityRenderingExtQueryType; + + +typedef enum UnityRenderingExtTextureFormat +{ + kUnityRenderingExtFormatNone = 0, kUnityRenderingExtFormatFirst = kUnityRenderingExtFormatNone, + + // sRGB formats + kUnityRenderingExtFormatR8_SRGB, + kUnityRenderingExtFormatR8G8_SRGB, + kUnityRenderingExtFormatR8G8B8_SRGB, + kUnityRenderingExtFormatR8G8B8A8_SRGB, + + // 8 bit integer formats + kUnityRenderingExtFormatR8_UNorm, + kUnityRenderingExtFormatR8G8_UNorm, + kUnityRenderingExtFormatR8G8B8_UNorm, + kUnityRenderingExtFormatR8G8B8A8_UNorm, + kUnityRenderingExtFormatR8_SNorm, + kUnityRenderingExtFormatR8G8_SNorm, + kUnityRenderingExtFormatR8G8B8_SNorm, + kUnityRenderingExtFormatR8G8B8A8_SNorm, + kUnityRenderingExtFormatR8_UInt, + kUnityRenderingExtFormatR8G8_UInt, + kUnityRenderingExtFormatR8G8B8_UInt, + kUnityRenderingExtFormatR8G8B8A8_UInt, + kUnityRenderingExtFormatR8_SInt, + kUnityRenderingExtFormatR8G8_SInt, + kUnityRenderingExtFormatR8G8B8_SInt, + kUnityRenderingExtFormatR8G8B8A8_SInt, + + // 16 bit integer formats + kUnityRenderingExtFormatR16_UNorm, + kUnityRenderingExtFormatR16G16_UNorm, + kUnityRenderingExtFormatR16G16B16_UNorm, + kUnityRenderingExtFormatR16G16B16A16_UNorm, + kUnityRenderingExtFormatR16_SNorm, + kUnityRenderingExtFormatR16G16_SNorm, + kUnityRenderingExtFormatR16G16B16_SNorm, + kUnityRenderingExtFormatR16G16B16A16_SNorm, + kUnityRenderingExtFormatR16_UInt, + kUnityRenderingExtFormatR16G16_UInt, + kUnityRenderingExtFormatR16G16B16_UInt, + kUnityRenderingExtFormatR16G16B16A16_UInt, + kUnityRenderingExtFormatR16_SInt, + kUnityRenderingExtFormatR16G16_SInt, + kUnityRenderingExtFormatR16G16B16_SInt, + kUnityRenderingExtFormatR16G16B16A16_SInt, + + // 32 bit integer formats + kUnityRenderingExtFormatR32_UInt, + kUnityRenderingExtFormatR32G32_UInt, + kUnityRenderingExtFormatR32G32B32_UInt, + kUnityRenderingExtFormatR32G32B32A32_UInt, + kUnityRenderingExtFormatR32_SInt, + kUnityRenderingExtFormatR32G32_SInt, + kUnityRenderingExtFormatR32G32B32_SInt, + kUnityRenderingExtFormatR32G32B32A32_SInt, + + // HDR formats + kUnityRenderingExtFormatR16_SFloat, + kUnityRenderingExtFormatR16G16_SFloat, + kUnityRenderingExtFormatR16G16B16_SFloat, + kUnityRenderingExtFormatR16G16B16A16_SFloat, + kUnityRenderingExtFormatR32_SFloat, + kUnityRenderingExtFormatR32G32_SFloat, + kUnityRenderingExtFormatR32G32B32_SFloat, + kUnityRenderingExtFormatR32G32B32A32_SFloat, + + // Luminance and Alpha format + kUnityRenderingExtFormatL8_UNorm, + kUnityRenderingExtFormatA8_UNorm, + kUnityRenderingExtFormatA16_UNorm, + + // BGR formats + kUnityRenderingExtFormatB8G8R8_SRGB, + kUnityRenderingExtFormatB8G8R8A8_SRGB, + kUnityRenderingExtFormatB8G8R8_UNorm, + kUnityRenderingExtFormatB8G8R8A8_UNorm, + kUnityRenderingExtFormatB8G8R8_SNorm, + kUnityRenderingExtFormatB8G8R8A8_SNorm, + kUnityRenderingExtFormatB8G8R8_UInt, + kUnityRenderingExtFormatB8G8R8A8_UInt, + kUnityRenderingExtFormatB8G8R8_SInt, + kUnityRenderingExtFormatB8G8R8A8_SInt, + + // 16 bit packed formats + kUnityRenderingExtFormatR4G4B4A4_UNormPack16, + kUnityRenderingExtFormatB4G4R4A4_UNormPack16, + kUnityRenderingExtFormatR5G6B5_UNormPack16, + kUnityRenderingExtFormatB5G6R5_UNormPack16, + kUnityRenderingExtFormatR5G5B5A1_UNormPack16, + kUnityRenderingExtFormatB5G5R5A1_UNormPack16, + kUnityRenderingExtFormatA1R5G5B5_UNormPack16, + + // Packed formats + kUnityRenderingExtFormatE5B9G9R9_UFloatPack32, + kUnityRenderingExtFormatB10G11R11_UFloatPack32, + + kUnityRenderingExtFormatA2B10G10R10_UNormPack32, + kUnityRenderingExtFormatA2B10G10R10_UIntPack32, + kUnityRenderingExtFormatA2B10G10R10_SIntPack32, + kUnityRenderingExtFormatA2R10G10B10_UNormPack32, + kUnityRenderingExtFormatA2R10G10B10_UIntPack32, + kUnityRenderingExtFormatA2R10G10B10_SIntPack32, + kUnityRenderingExtFormatA2R10G10B10_XRSRGBPack32, + kUnityRenderingExtFormatA2R10G10B10_XRUNormPack32, + kUnityRenderingExtFormatR10G10B10_XRSRGBPack32, + kUnityRenderingExtFormatR10G10B10_XRUNormPack32, + kUnityRenderingExtFormatA10R10G10B10_XRSRGBPack32, + kUnityRenderingExtFormatA10R10G10B10_XRUNormPack32, + + // ARGB formats... TextureFormat legacy + kUnityRenderingExtFormatA8R8G8B8_SRGB, + kUnityRenderingExtFormatA8R8G8B8_UNorm, + kUnityRenderingExtFormatA32R32G32B32_SFloat, + + // Depth Stencil for formats + kUnityRenderingExtFormatD16_UNorm, + kUnityRenderingExtFormatD24_UNorm, + kUnityRenderingExtFormatD24_UNorm_S8_UInt, + kUnityRenderingExtFormatD32_SFloat, + kUnityRenderingExtFormatD32_SFloat_S8_UInt, + kUnityRenderingExtFormatS8_UInt, + + // Compression formats + kUnityRenderingExtFormatRGBA_DXT1_SRGB, + kUnityRenderingExtFormatRGBA_DXT1_UNorm, + kUnityRenderingExtFormatRGBA_DXT3_SRGB, + kUnityRenderingExtFormatRGBA_DXT3_UNorm, + kUnityRenderingExtFormatRGBA_DXT5_SRGB, + kUnityRenderingExtFormatRGBA_DXT5_UNorm, + kUnityRenderingExtFormatR_BC4_UNorm, + kUnityRenderingExtFormatR_BC4_SNorm, + kUnityRenderingExtFormatRG_BC5_UNorm, + kUnityRenderingExtFormatRG_BC5_SNorm, + kUnityRenderingExtFormatRGB_BC6H_UFloat, + kUnityRenderingExtFormatRGB_BC6H_SFloat, + kUnityRenderingExtFormatRGBA_BC7_SRGB, + kUnityRenderingExtFormatRGBA_BC7_UNorm, + + kUnityRenderingExtFormatRGB_PVRTC_2Bpp_SRGB, + kUnityRenderingExtFormatRGB_PVRTC_2Bpp_UNorm, + kUnityRenderingExtFormatRGB_PVRTC_4Bpp_SRGB, + kUnityRenderingExtFormatRGB_PVRTC_4Bpp_UNorm, + kUnityRenderingExtFormatRGBA_PVRTC_2Bpp_SRGB, + kUnityRenderingExtFormatRGBA_PVRTC_2Bpp_UNorm, + kUnityRenderingExtFormatRGBA_PVRTC_4Bpp_SRGB, + kUnityRenderingExtFormatRGBA_PVRTC_4Bpp_UNorm, + + kUnityRenderingExtFormatRGB_ETC_UNorm, + kUnityRenderingExtFormatRGB_ETC2_SRGB, + kUnityRenderingExtFormatRGB_ETC2_UNorm, + kUnityRenderingExtFormatRGB_A1_ETC2_SRGB, + kUnityRenderingExtFormatRGB_A1_ETC2_UNorm, + kUnityRenderingExtFormatRGBA_ETC2_SRGB, + kUnityRenderingExtFormatRGBA_ETC2_UNorm, + + kUnityRenderingExtFormatR_EAC_UNorm, + kUnityRenderingExtFormatR_EAC_SNorm, + kUnityRenderingExtFormatRG_EAC_UNorm, + kUnityRenderingExtFormatRG_EAC_SNorm, + + kUnityRenderingExtFormatRGBA_ASTC4X4_SRGB, + kUnityRenderingExtFormatRGBA_ASTC4X4_UNorm, + kUnityRenderingExtFormatRGBA_ASTC5X5_SRGB, + kUnityRenderingExtFormatRGBA_ASTC5X5_UNorm, + kUnityRenderingExtFormatRGBA_ASTC6X6_SRGB, + kUnityRenderingExtFormatRGBA_ASTC6X6_UNorm, + kUnityRenderingExtFormatRGBA_ASTC8X8_SRGB, + kUnityRenderingExtFormatRGBA_ASTC8X8_UNorm, + kUnityRenderingExtFormatRGBA_ASTC10X10_SRGB, + kUnityRenderingExtFormatRGBA_ASTC10X10_UNorm, + kUnityRenderingExtFormatRGBA_ASTC12X12_SRGB, + kUnityRenderingExtFormatRGBA_ASTC12X12_UNorm, + + // Video formats + kUnityRenderingExtFormatYUV2, + + // Automatic formats, back-end decides + kUnityRenderingExtFormatDepthAuto_removed_donotuse, + kUnityRenderingExtFormatShadowAuto_removed_donotuse, + kUnityRenderingExtFormatVideoAuto_removed_donotuse, + + // ASTC hdr profile + kUnityRenderingExtFormatRGBA_ASTC4X4_UFloat, + kUnityRenderingExtFormatRGBA_ASTC5X5_UFloat, + kUnityRenderingExtFormatRGBA_ASTC6X6_UFloat, + kUnityRenderingExtFormatRGBA_ASTC8X8_UFloat, + kUnityRenderingExtFormatRGBA_ASTC10X10_UFloat, + kUnityRenderingExtFormatRGBA_ASTC12X12_UFloat, + + kUnityRenderingExtFormatLast = kUnityRenderingExtFormatRGBA_ASTC12X12_UFloat, // Remove? +} UnityRenderingExtTextureFormat; + + +typedef struct UnityRenderingExtBeforeDrawCallParams +{ + void* vertexShader; // bound vertex shader (platform dependent) + void* fragmentShader; // bound fragment shader (platform dependent) + void* geometryShader; // bound geometry shader (platform dependent) + void* hullShader; // bound hull shader (platform dependent) + void* domainShader; // bound domain shader (platform dependent) + int eyeIndex; // the index of the current stereo "eye" being currently rendered. +} UnityRenderingExtBeforeDrawCallParams; + + +typedef struct UnityRenderingExtCustomBlitParams +{ + UnityTextureID source; // source texture + UnityRenderBuffer destination; // destination surface + unsigned int command; // command for the custom blit - could be any UnityRenderingExtCustomBlitCommands command or custom ones. + unsigned int commandParam; // custom parameters for the command + unsigned int commandFlags; // custom flags for the command +} UnityRenderingExtCustomBlitParams; + +// Deprecated. Use UnityRenderingExtTextureUpdateParamsV2 and CommandBuffer.IssuePluginCustomTextureUpdateV2 instead. +// Only supports DX11, GLES, Metal +typedef struct UnityRenderingExtTextureUpdateParamsV1 +{ + void* texData; // source data for the texture update. Must be set by the plugin + unsigned int userData; // user defined data. Set by the plugin + + unsigned int textureID; // texture ID of the texture to be updated. + UnityRenderingExtTextureFormat format; // format of the texture to be updated + unsigned int width; // width of the texture + unsigned int height; // height of the texture + unsigned int bpp; // texture bytes per pixel. +} UnityRenderingExtTextureUpdateParamsV1; + +// Deprecated. Use UnityRenderingExtTextureUpdateParamsV2 and CommandBuffer.IssuePluginCustomTextureUpdateV2 instead. +// Only supports DX11, GLES, Metal +typedef UnityRenderingExtTextureUpdateParamsV1 UnityRenderingExtTextureUpdateParams; + +// Type of the "data" parameter passed when callbacks registered with CommandBuffer.IssuePluginCustomTextureUpdateV2 are called. +// Supports DX11, GLES, Metal, and Switch (also possibly PS4, PSVita in the future) +typedef struct UnityRenderingExtTextureUpdateParamsV2 +{ + void* texData; // source data for the texture update. Must be set by the plugin + intptr_t textureID; // texture ID of the texture to be updated. + unsigned int userData; // user defined data. Set by the plugin + UnityRenderingExtTextureFormat format; // format of the texture to be updated + unsigned int width; // width of the texture + unsigned int height; // height of the texture + unsigned int bpp; // texture bytes per pixel. +} UnityRenderingExtTextureUpdateParamsV2; + + +// Certain Unity APIs (GL.IssuePluginEventAndData, CommandBuffer.IssuePluginEventAndData) can callback into native plugins. +// Provide them with an address to a function of this signature. +typedef void (UNITY_INTERFACE_API * UnityRenderingEventAndData)(int eventId, void* data); + + +#ifdef __cplusplus +extern "C" { +#endif + +// If exported by a plugin, this function will be called for all the events in UnityRenderingExtEventType +void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityRenderingExtEvent(UnityRenderingExtEventType event, void* data); +// If exported by a plugin, this function will be called to query the plugin for the queries in UnityRenderingExtQueryType +bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityRenderingExtQuery(UnityRenderingExtQueryType query); + +#ifdef __cplusplus +} +#endif