Browse Source

Replaced manually copied native PSSR plugin with an auto-building package

pssr
Nico de Poel 1 year ago
parent
commit
b289f025c1
  1. 2
      .gitignore
  2. 3
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5.meta
  3. BIN
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5/PSSRPlugin.prx
  4. 77
      Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5/PSSRPlugin.prx.meta
  5. 2
      Packages/com.ww1gameseries.pssr/Editor.meta
  6. 186
      Packages/com.ww1gameseries.pssr/Editor/BuildPackageLibs.cs
  7. 11
      Packages/com.ww1gameseries.pssr/Editor/BuildPackageLibs.cs.meta
  8. 77
      Packages/com.ww1gameseries.pssr/Editor/BuildUtils.cs
  9. 11
      Packages/com.ww1gameseries.pssr/Editor/BuildUtils.cs.meta
  10. 18
      Packages/com.ww1gameseries.pssr/Editor/PSSRPlugin.Editor.asmdef
  11. 7
      Packages/com.ww1gameseries.pssr/Editor/PSSRPlugin.Editor.asmdef.meta
  12. 68
      Packages/com.ww1gameseries.pssr/Editor/SDKUtils.cs
  13. 11
      Packages/com.ww1gameseries.pssr/Editor/SDKUtils.cs.meta
  14. 8
      Packages/com.ww1gameseries.pssr/Runtime.meta
  15. 3
      Packages/com.ww1gameseries.pssr/Runtime/AssemblyInfo.cs
  16. 11
      Packages/com.ww1gameseries.pssr/Runtime/AssemblyInfo.cs.meta
  17. 8
      Packages/com.ww1gameseries.pssr/Runtime/LibraryInfo.cs
  18. 11
      Packages/com.ww1gameseries.pssr/Runtime/LibraryInfo.cs.meta
  19. 16
      Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.Runtime.asmdef
  20. 7
      Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.Runtime.asmdef.meta
  21. 164
      Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.cs
  22. 11
      Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.cs.meta
  23. 85
      Packages/com.ww1gameseries.pssr/Source~/PSSRPlugin.vcxproj
  24. 39
      Packages/com.ww1gameseries.pssr/Source~/PSSRPlugin.vcxproj.filters
  25. 64
      Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphics.h
  26. 32
      Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphicsAgcPS5.h
  27. 21
      Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphicsPS5.h
  28. 209
      Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityInterface.h
  29. 37
      Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityLog.h
  30. 606
      Packages/com.ww1gameseries.pssr/Source~/pssrplugin.cpp
  31. 13
      Packages/com.ww1gameseries.pssr/package.json
  32. 7
      Packages/com.ww1gameseries.pssr/package.json.meta
  33. 6
      Packages/packages-lock.json

2
.gitignore

@ -12,3 +12,5 @@ screenshot-*.png
Tools/PSSRPlugin/Prospero_Debug/
*.user
Tools/PSSRPlugin/Prospero_Release/
Prospero_Debug/
Prospero_Release/

3
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5.meta

@ -1,3 +0,0 @@
fileFormatVersion: 2
guid: 32c5585f0ac1473aaa942ede8bc01712
timeCreated: 1730718066

BIN
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5/PSSRPlugin.prx

77
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins/PS5/PSSRPlugin.prx.meta

@ -1,77 +0,0 @@
fileFormatVersion: 2
guid: 82cb3c505a5252e4db0b661d9ccd67cb
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 1
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 1
Exclude GameCoreScarlett: 1
Exclude GameCoreXboxOne: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude PS4: 1
Exclude PS5: 0
Exclude Win: 1
Exclude Win64: 1
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
PS4: PS4
second:
enabled: 0
settings: {}
- first:
PS5: PS5
second:
enabled: 1
settings: {}
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

2
Packages/com.unity.postprocessing@3.2.2/PostProcessing/Runtime/Effects/Upscaling/Plugins.meta → Packages/com.ww1gameseries.pssr/Editor.meta

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5fe0a1d4497ee1c43bca193c0efc0b4f
guid: 90b76d351f2ce6c4e92b07204ce4b3a1
folderAsset: yes
DefaultImporter:
externalObjects: {}

186
Packages/com.ww1gameseries.pssr/Editor/BuildPackageLibs.cs

@ -0,0 +1,186 @@
#if UNITY_EDITOR_WIN
using System;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.UnityLinker;
using UnityEngine;
using PlayerSettings = UnityEditor.PlayerSettings;
using WW1.PlayStation;
internal class BuildPackageLibs : IPreprocessBuildWithReport, IMovePRXCallback
{
public int callbackOrder => 0;
static string PackageName => "com.ww1gameseries.pssr";
static string SourcePath => $"Packages/{PackageName}/Source~";
const int k_PRXBuildTimeOutS = 600; //10 minutes is the max time allowed to build the PRX
#region CompileLibs
readonly string[] m_CompileAgainstLibs = new string[]
{
"SceSysmodule_stub_weak",
"ScePsml",
"ScePsml_stub_weak",
"SceAgcGnmp",
"SceAgc",
"SceAgcCore",
"SceAgcGpuAddress",
"SceVideoOut_stub_weak",
"SceAgcDriver_stub_weak",
"SceAgc_stub_weak",
};
#endregion
public void OnPreprocessBuild(BuildReport report)
{
var buildTarget = report.summary.platform;
if (!IsBuildTargetValid(buildTarget))
{
return;
}
string prxPath = GetPRXBuildLocation(buildTarget);
string prxDir = Path.GetDirectoryName(prxPath);
if (IsPRXRebuildRequired(prxPath))
{
if (!Directory.Exists(prxDir))
{
if (string.IsNullOrWhiteSpace(prxDir))
{
throw new BuildFailedException("No PRX Directory");
}
Directory.CreateDirectory(prxDir);
}
BuildPackagePRX(buildTarget, prxPath, m_CompileAgainstLibs);
}
}
public void MovePRXToBuildLocation(BuildTarget target, string buildOutputLocation, bool developmentBuild)
{
if (!IsBuildTargetValid(target))
{
return;
}
string projectDir = Application.dataPath.Replace("/Assets", "");
string stagingArea = BuildUtils.GetStagingAreaLocationFor(target, projectDir, buildOutputLocation);
CopyLibraryPRXToStagingArea(GetPRXBuildLocation(target), stagingArea);
}
static bool IsPRXRebuildRequired(string prxPath)
{
if (!File.Exists(prxPath))
{
return true;
}
DateTime prxLastWrite = File.GetLastWriteTimeUtc(prxPath);
if (BuildUtils.HaveSourceFilesBeenModifiedSince(SourcePath, prxLastWrite))
{
return true;
}
return false;
}
static void BuildPackagePRX(BuildTarget target, string outputPath, string[] compileAgainstLibs)
{
string sdkLoc = Environment.GetEnvironmentVariable(SDKUtils.GetSdkEnvVarFor(target));
string clangLoc = $"{sdkLoc}/host_tools/bin/{SDKUtils.GetClangFor(target)}";
string allSourcePaths = string.Empty;
string[] allDirs = Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories);
//Include the base folder also, if it has cpp files in it
if (Directory.GetFiles(SourcePath, "*.cpp").Length > 0)
{
allSourcePaths += $"\"{Path.GetFullPath(Path.Combine(SourcePath, "*.cpp"))}\" ";
}
foreach (var dir in allDirs)
{
if (Directory.GetFiles(dir, "*.cpp").Length == 0)
{
continue;
}
allSourcePaths += $"\"{Path.GetFullPath(Path.Combine(dir, "*.cpp"))}\" ";
}
string allLinkLibs = string.Empty;
foreach (var lib in compileAgainstLibs)
{
allLinkLibs += $"-l {lib} ";
}
//Additionally include the common includes
string command = $"-D\"NDEBUG\" -O2 -Wall -o\"{outputPath}\" {allSourcePaths} --for-linker=--oformat=prx {allLinkLibs}";
ProcessStartInfo startInfo = new ProcessStartInfo(clangLoc, command)
{
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardError = true,
};
Console.WriteLine($"Building PRX with {clangLoc} {command}");
Process proc = Process.Start(startInfo);
string errorOutput = proc.StandardError.ReadToEnd();
proc.WaitForExit(k_PRXBuildTimeOutS);
if (!proc.HasExited)
{
proc.Kill();
throw new BuildFailedException($"PRX Build Timed Out\n{errorOutput}");
}
if (proc.ExitCode != 0)
{
throw new BuildFailedException(errorOutput);
}
}
static void CopyLibraryPRXToStagingArea(string prxLocation, string stagingArea)
{
string copyPath = Path.Combine(stagingArea, LibraryInfo.LibraryNameWithExtension);
if (!Directory.Exists(stagingArea))
{
Directory.CreateDirectory(stagingArea);
}
File.Copy(prxLocation, copyPath, true);
}
static string GetPRXBuildLocation(BuildTarget target)
{
//Example Path: Library/SourceGeneratedPlugins/PS5/7000045/CommonDialog.prx
string relativePath = Path.Combine("Library", "SourceGeneratedPlugins", target.ToString(),
SDKUtils.GetSDKVersionString(target), $"{LibraryInfo.LibraryNameWithExtension}");
return Path.GetFullPath(relativePath);
}
static bool IsBuildTargetValid(BuildTarget target)
{
return target is BuildTarget.PS5;
}
}
internal interface IMovePRXCallback : IUnityLinkerProcessor
{
string IUnityLinkerProcessor.GenerateAdditionalLinkXmlFile(BuildReport report, UnityLinkerBuildPipelineData data)
{
//In 2021.3 report can return null for non-playstation platforms
if (report == null)
{
return string.Empty;
}
MovePRXToBuildLocation(report.summary.platform, report.summary.outputPath, report.summary.options.HasFlag(BuildOptions.Development));
return string.Empty;
}
public void MovePRXToBuildLocation(BuildTarget target, string buildOutputLocation, bool developmentBuild);
}
#endif

11
Packages/com.ww1gameseries.pssr/Editor/BuildPackageLibs.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9ecb3065343dab3468b39fb88f387d0a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

77
Packages/com.ww1gameseries.pssr/Editor/BuildUtils.cs

@ -0,0 +1,77 @@
#if UNITY_EDITOR_WIN
using System;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
internal static class BuildUtils
{
internal static readonly string kBuildFolderName = "Build";
internal static bool HaveSourceFilesBeenModifiedSince(string sourcePath, DateTime lastPrxWrite)
{
DateTime latestWriteTime = DateTime.MinValue;
DirectoryInfo di = new DirectoryInfo(sourcePath);
foreach (var file in di.GetFiles("*.cpp", SearchOption.AllDirectories))
{
var fileLW = File.GetLastWriteTimeUtc(file.FullName);
latestWriteTime = (fileLW > latestWriteTime) ? fileLW: latestWriteTime;
}
foreach (var file in di.GetFiles("*.h", SearchOption.AllDirectories))
{
var fileLW = File.GetLastWriteTimeUtc(file.FullName);
latestWriteTime = (fileLW > latestWriteTime) ? fileLW: latestWriteTime;
}
System.Console.WriteLine($"latestWriteTime:{latestWriteTime} lastwritepre:{lastPrxWrite}");
if (latestWriteTime < lastPrxWrite)
{
System.Console.WriteLine($"skipping package prebuild step. No changes detected");
return false;
}
return true;
}
internal static string GetStagingAreaLocationFor(BuildTarget buildPlatform, string projectDir, string outputPath)
{
string stagingArea;
//2021.3 (pre-IBP) has StagingArea as a root to just the StagingArea Folder
//2022 (IBP) uses the [BUILD_OUTPUT]/Build path as its StagingArea and ignores the staging area
//completely
#if UNITY_2022_2_OR_NEWER
if (buildPlatform == BuildTarget.PS4)
{
stagingArea = Path.Combine(outputPath, kBuildFolderName, "Media", "Plugins");
}
else if (buildPlatform == BuildTarget.PS5)
{
stagingArea = Path.Combine(projectDir, "Temp", "StagingArea", "User", "Media", "Plugins");
}else
{
throw new InvalidOperationException($"Cannot get staging area for {buildPlatform}");
}
#else
//PS4 will auto copy the contents of Data to the media folder and if you have already created a media folder
//(i.e. StagingArea/Media) it will throw an error, so instead just copy to data and allow the PS4 build process to
//do the copying to Media
if (buildPlatform == BuildTarget.PS4)
{
stagingArea = Path.Combine(projectDir, "Temp", "StagingArea", "Data", "Plugins");
}
else if (buildPlatform == BuildTarget.PS5)
{
stagingArea = Path.Combine(projectDir, "Temp", "StagingArea", "Media", "Plugins");
}
else
{
throw new InvalidOperationException($"Cannot get staging area for {buildPlatform}");
}
#endif
return stagingArea;
}
}
#endif

11
Packages/com.ww1gameseries.pssr/Editor/BuildUtils.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a9c85a4918ae7274782eafae60d67746
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

18
Packages/com.ww1gameseries.pssr/Editor/PSSRPlugin.Editor.asmdef

@ -0,0 +1,18 @@
{
"name": "PSSRPlugin.Editor",
"rootNamespace": "",
"references": [
"PSSRPlugin.Runtime"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

7
Packages/com.ww1gameseries.pssr/Editor/PSSRPlugin.Editor.asmdef.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: efdaa6148c335c646b2b4e1dd3e6bdb6
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

68
Packages/com.ww1gameseries.pssr/Editor/SDKUtils.cs

@ -0,0 +1,68 @@
#if UNITY_EDITOR_WIN
using System;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
internal static class SDKUtils
{
internal static string GetSDKVersionString(BuildTarget target)
{
string verstring = string.Empty;
string sdkPath = System.Environment.GetEnvironmentVariable(GetSdkEnvVarFor(target));
if (sdkPath != null)
{
string versionFile = Path.Combine(sdkPath, "target/include/sdk_version.h");
if (File.Exists(versionFile))
{
string[] lines = File.ReadAllLines(versionFile);
foreach (string line in lines)
{
//Extract the value following #define SCE_PROSPERO_SDK_VERSION
string regexPattern = $@"#define\s+{GetSdkVersionStringFor(target)}\s+\(\s*0x([0-9a-fA-F]+)u\s*\)";
Match match = Regex.Match(line, regexPattern);
if (match.Success)
{
verstring = match.Groups[1].Value;
}
}
}
}
return verstring;
}
internal static string GetSdkEnvVarFor(BuildTarget target)
{
switch (target)
{
case BuildTarget.PS5:
return "SCE_PROSPERO_SDK_DIR";
default:
throw new InvalidOperationException($"Cannot get env var for {target}");
}
}
internal static string GetClangFor(BuildTarget target)
{
switch (target)
{
case BuildTarget.PS5:
return "prospero-clang.exe";
default:
throw new InvalidOperationException($"Cannot get clang for {target}");
}
}
static string GetSdkVersionStringFor(BuildTarget target)
{
switch (target)
{
case BuildTarget.PS5:
return "SCE_PROSPERO_SDK_VERSION";
default:
throw new InvalidOperationException($"Cannot get SDK for {target}");
}
}
}
#endif

11
Packages/com.ww1gameseries.pssr/Editor/SDKUtils.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 053e3eab3ada35648ae6894cb24855c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Packages/com.ww1gameseries.pssr/Runtime.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c73d52c9900b2ae4bba5ec72be77f33b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

3
Packages/com.ww1gameseries.pssr/Runtime/AssemblyInfo.cs

@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("PSSRPlugin.Editor")]

11
Packages/com.ww1gameseries.pssr/Runtime/AssemblyInfo.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6978c53bdde0f304daa0bf3a8ab67bc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Packages/com.ww1gameseries.pssr/Runtime/LibraryInfo.cs

@ -0,0 +1,8 @@
namespace WW1.PlayStation
{
internal static class LibraryInfo
{
internal const string LibraryName = "PSSRPlugin";
internal static string LibraryNameWithExtension => $"{LibraryName}.prx";
}
}

11
Packages/com.ww1gameseries.pssr/Runtime/LibraryInfo.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc79f70c3d6f5694fb6670287b08929d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

16
Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.Runtime.asmdef

@ -0,0 +1,16 @@
{
"name": "PSSRPlugin.Runtime",
"references": [],
"includePlatforms": [
"Editor",
"PS5"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

7
Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.Runtime.asmdef.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 75c98c12b3993194db6c4bc91f7afa0c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

164
Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.cs

@ -0,0 +1,164 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;
namespace WW1.PlayStation
{
public static class PSSRPlugin
{
public static readonly uint MaxNumContexts = 4;
public enum Event
{
Create,
Dispatch,
Destroy,
Capture,
}
public static void IssuePluginEvent<T>(CommandBuffer cmd, Event pluginEvent, NativeData<T> data) where T : struct
{
cmd.IssuePluginEventAndData(GetRenderEventAndDataFunc(), (int)pluginEvent, data.GetPointer());
}
[DllImport(LibraryInfo.LibraryName)]
public static extern IntPtr GetRenderEventAndDataFunc();
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_Init")]
public static extern int Init();
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_Release")]
public static extern void Release();
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_CreateContext")]
public static extern int CreateContext(ref InitParams initParams, out IntPtr outputColorTexturePtr);
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_DestroyContext")]
public static extern void DestroyContext(uint contextIndex);
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_Dispatch")]
public static extern void Dispatch(ref DispatchParams dispatchParams);
[DllImport(LibraryInfo.LibraryName, EntryPoint = "PSSR_RequestCapture")]
public static extern int RequestCapture(uint contextIndex, byte frameNum = 64);
[StructLayout(LayoutKind.Sequential)]
public struct InitParams
{
public uint contextIndex;
public uint displayWidth;
public uint displayHeight;
public uint maxRenderWidth;
public uint maxRenderHeight;
public uint autoKeepCopies;
}
[StructLayout(LayoutKind.Sequential)]
public struct DispatchParams
{
public uint contextIndex;
public IntPtr color;
public IntPtr depth;
public IntPtr prevDepth;
public IntPtr motionVectors;
public IntPtr prevMotionVectors;
public IntPtr exposure;
public IntPtr reactiveMask;
public IntPtr outputColor;
public uint renderWidth;
public uint renderHeight;
public Vector2 jitter;
public Vector2 motionVectorScale;
public Matrix4x4 camProjectionNoJitter;
public Vector3 camForward;
public Vector3 camUp;
public Vector3 camRight;
public double camPositionX;
public double camPositionY;
public double camPositionZ;
public float camNear;
public float camFar;
public float preExposure;
public uint resetHistory;
public OptionFlags flags;
public void FromCamera(Camera cam)
{
camProjectionNoJitter = cam.nonJitteredProjectionMatrix;
camForward = cam.transform.forward;
camUp = cam.transform.up;
camRight = cam.transform.right;
camPositionX = cam.transform.position.x;
camPositionY = cam.transform.position.y;
camPositionZ = cam.transform.position.z;
camNear = cam.nearClipPlane;
camFar = cam.farClipPlane;
}
}
[Flags]
public enum OptionFlags: uint
{
None = 0u,
ViewSpaceDepth = 1u << 14,
ReverseDepth = 1u << 15,
AutoExposure = 1u << 16,
PassThrough = 1u << 31,
}
[StructLayout(LayoutKind.Sequential)]
public struct DestroyParams
{
public uint contextIndex;
}
[StructLayout(LayoutKind.Sequential)]
public struct CaptureParams
{
public uint contextIndex;
public byte frameNum;
}
/// <summary>
/// Helper class to deal with all the nasty business of converting managed struct data into a pointer to native memory for use with plugin events.
/// </summary>
public class NativeData<T> where T : struct
{
private T _value;
private IntPtr _nativeBuffer = IntPtr.Zero;
public ref T Value => ref _value;
public void Initialize()
{
if (_nativeBuffer != IntPtr.Zero)
return;
_nativeBuffer = Marshal.AllocHGlobal(Marshal.SizeOf<T>());
}
public void Destroy()
{
if (_nativeBuffer == IntPtr.Zero)
return;
Marshal.FreeHGlobal(_nativeBuffer);
_nativeBuffer = IntPtr.Zero;
}
public IntPtr GetPointer()
{
Marshal.StructureToPtr(_value, _nativeBuffer, false);
return _nativeBuffer;
}
}
}
}

11
Packages/com.ww1gameseries.pssr/Runtime/PSSRPlugin.cs.meta

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 272bc1969de41c147b9279094be5afa8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

85
Packages/com.ww1gameseries.pssr/Source~/PSSRPlugin.vcxproj

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Prospero">
<Configuration>Debug</Configuration>
<Platform>Prospero</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Prospero">
<Configuration>Release</Configuration>
<Platform>Prospero</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{cfc8c665-7287-4dac-9016-2d97e70b63be}</ProjectGuid>
<ProsperoSdkVersion />
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Prospero'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Prospero'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup Condition="'$(DebuggerFlavor)'=='ProsperoDebugger'" Label="OverrideDebuggerDefaults">
<!--LocalDebuggerCommand>$(TargetPath)</LocalDebuggerCommand-->
<!--LocalDebuggerCommandArguments></LocalDebuggerCommandArguments-->
<!--LocalDebuggerTarget></LocalDebuggerTarget-->
<!--LocalDebuggerWorkingDirectory>$(ProjectDir)</LocalDebuggerWorkingDirectory-->
<!--LocalRunCommandLine></LocalRunCommandLine-->
</PropertyGroup>
<ImportGroup Label="ExtensionSettings">
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.props')" Project="$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Prospero'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Prospero'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Prospero'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions);</PreprocessorDefinitions>
<GenerateDebugInformation>true</GenerateDebugInformation>
</ClCompile>
<Link>
<Addressing>NonAslr</Addressing>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>-lSceSysmodule_stub_weak;-lScePsml;-lScePsml_stub_weak;-lSceAgcGnmp;-lSceAgc;-lSceAgcCore;-lSceAgcGpuAddress;-lSceVideoOut_stub_weak;-lSceAgcDriver_stub_weak;-lSceAgc_stub_weak</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Prospero'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions);</PreprocessorDefinitions>
<OptimizationLevel>Level2</OptimizationLevel>
</ClCompile>
<Link>
<AdditionalDependencies>-lSceSysmodule_stub_weak;-lScePsml;-lScePsml_stub_weak;-lSceAgcGnmp;-lSceAgc;-lSceAgcCore;-lSceAgcGpuAddress;-lSceVideoOut_stub_weak;-lSceAgcDriver_stub_weak;-lSceAgc_stub_weak</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="pssrplugin.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="UnityPluginAPI\IUnityGraphics.h" />
<ClInclude Include="UnityPluginAPI\IUnityGraphicsAgcPS5.h" />
<ClInclude Include="UnityPluginAPI\IUnityGraphicsPS5.h" />
<ClInclude Include="UnityPluginAPI\IUnityInterface.h" />
<ClInclude Include="UnityPluginAPI\IUnityLog.h" />
</ItemGroup>
<Import Condition="'$(ConfigurationType)' == 'Makefile' and Exists('$(VCTargetsPath)\Platforms\$(Platform)\SCE.Makefile.$(Platform).targets')" Project="$(VCTargetsPath)\Platforms\$(Platform)\SCE.Makefile.$(Platform).targets" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Condition="Exists('$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.targets')" Project="$(VCTargetsPath)\BuildCustomizations\OrbisWavePsslc.targets" />
</ImportGroup>
</Project>

39
Packages/com.ww1gameseries.pssr/Source~/PSSRPlugin.vcxproj.filters

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cxx;cc;s;asm</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;pssli</Extensions>
</Filter>
<Filter Include="Shader Files">
<UniqueIdentifier>{5FAE8098-8EE5-44A0-ABB6-C797B807CDE6}</UniqueIdentifier>
<Extensions>pssl;scu</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pssrplugin.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="UnityPluginAPI\IUnityGraphics.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnityPluginAPI\IUnityInterface.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnityPluginAPI\IUnityLog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnityPluginAPI\IUnityGraphicsAgcPS5.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnityPluginAPI\IUnityGraphicsPS5.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

64
Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphics.h

@ -0,0 +1,64 @@
// 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, removed
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
kUnityGfxRendererReservedCFE = 29
} 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);

32
Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphicsAgcPS5.h

@ -0,0 +1,32 @@
// Unity Native Plugin API copyright © 2021 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
#if UNITY
#include "Runtime/PluginInterface/Headers/IUnityInterface.h"
#else
#include "IUnityInterface.h"
#endif
#include <agc/commandbuffer.h>
#include <agc/registerstructs.h>
#include <stdint.h>
// Should only be used on the rendering thread unless noted otherwise.
UNITY_DECLARE_INTERFACE(IUnityGraphicsAgcPS5)
{
void *(UNITY_INTERFACE_API * AllocateGPUMemory)(size_t size, int alignment);
void(UNITY_INTERFACE_API * ReleaseGPUMemory)(void *data);
void* (UNITY_INTERFACE_API * AllocateContiguousPhysicalGPUMemory)(size_t size, int alignment);
void(UNITY_INTERFACE_API * ReleaseContiguousPhysicalGPUMemory)(void* data);
void(UNITY_INTERFACE_API * SubmitGraphics)(sce::Agc::PacketAddress dcbGpuAddr, uint32_t dcbSizeInDwords);
int (UNITY_INTERFACE_API * GetCurrentRenderTargetNum)();
void (UNITY_INTERFACE_API * GetCurrentRenderTarget)(sce::Agc::CxRenderTarget *renderTarget, int index);
void (UNITY_INTERFACE_API * GetCurrentDepthRenderTarget)(sce::Agc::CxDepthRenderTarget *depthRenderTarget);
};
UNITY_REGISTER_INTERFACE_GUID(0xE55C42913A8F419DULL, 0x872AB8A995684235ULL, IUnityGraphicsAgcPS5)

21
Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityGraphicsPS5.h

@ -0,0 +1,21 @@
// Unity Native Plugin API copyright © 2020 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"
// Should only be used on the rendering thread unless noted otherwise.
UNITY_DECLARE_INTERFACE(IUnityGraphicsPS5)
{
void* (UNITY_INTERFACE_API * GetGfxContext)();
void *(UNITY_INTERFACE_API * AllocateGPUMemory)(size_t size, int alignment);
void(UNITY_INTERFACE_API * ReleaseGPUMemory)(void *data);
void *(UNITY_INTERFACE_API * GetCurrentRenderTarget)(int index);
void *(UNITY_INTERFACE_API * GetCurrentDepthRenderTarget)();
};
UNITY_REGISTER_INTERFACE_GUID(0x74a62b5d78f14e8ULL, 0xa60947365e5561ceULL, IUnityGraphicsPS5)

209
Packages/com.ww1gameseries.pssr/Source~/UnityPluginAPI/IUnityInterface.h

@ -0,0 +1,209 @@
// 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(__ORBIS__) || defined(__PROSPERO__)
#define UNITY_INTERFACE_API
#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<IMyInterface>();
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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<typename TYPE>
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<TYPE>() \
{ \
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<TYPE>() 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<typename INTERFACE>
INTERFACE* Get()
{
return static_cast<INTERFACE*>(GetInterface(GetUnityInterfaceGUID<INTERFACE>()));
}
// Helper for RegisterInterface.
template<typename INTERFACE>
void Register(IUnityInterface* ptr)
{
RegisterInterface(GetUnityInterfaceGUID<INTERFACE>(), 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;

37
Packages/com.ww1gameseries.pssr/Source~/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)

606
Packages/com.ww1gameseries.pssr/Source~/pssrplugin.cpp

@ -0,0 +1,606 @@
#include <libsysmodule.h>
#include <agc.h>
#include <agc/gnmp/gnmp.h>
#include <psml_mfsr.h>
#include "UnityPluginAPI/IUnityInterface.h"
#include "UnityPluginAPI/IUnityLog.h"
#include "UnityPluginAPI/IUnityGraphics.h"
#include "UnityPluginAPI/IUnityGraphicsPS5.h"
#include "UnityPluginAPI/IUnityGraphicsAgcPS5.h"
using namespace sce::Agc;
using namespace sce::Psml;
static IUnityInterfaces* s_UnityInterfaces = nullptr;
static IUnityLog* s_Log = nullptr;
static IUnityGraphics* s_Graphics = nullptr;
static IUnityGraphicsPS5* s_GraphicsPS5 = nullptr; // Old Gnmp-based graphics API
static IUnityGraphicsAgcPS5* s_GraphicsAgcPS5 = nullptr; // New Agc-based graphics API (NGGC)
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
static bool s_mfsrInitialized = false;
static size_t s_mfsrSharedResourcesMemorySize = 0;
static off_t s_mfsrSharedResourcesMemoryAddress = 0;
static MfsrPhysicalMemoryBlock* s_mfsrSharedResourcesMemoryBlocks = nullptr;
static MfsrSharedResources s_mfsrSharedResources = nullptr;
struct PssrContext
{
Core::BasicContext agcContext;
size_t mfsrMemorySize = 0;
off_t mfsrMemoryPhysicalAddress = 0;
MfsrPhysicalMemoryBlock* mfsrMemoryBlocks = nullptr;
MfsrContext mfsrContext = nullptr;
Core::Texture outputColorTexture;
};
// "Multiple contexts (up to 4) can be generated to perform multiple MFSR processes within an application."
static const int MaxNumContexts = 4;
static PssrContext s_contexts[MaxNumContexts];
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType);
static void UNITY_INTERFACE_API OnRenderEventAndData(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<IUnityLog>();
s_Graphics = unityInterfaces->Get<IUnityGraphics>();
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);
}
// Freely defined function to pass a callback to plugin-specific scripts
extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventAndDataFunc()
{
return OnRenderEventAndData;
}
static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
switch (eventType)
{
case kUnityGfxDeviceEventInitialize:
{
s_RendererType = s_Graphics->GetRenderer();
if (s_RendererType != kUnityGfxRendererPS5 && s_RendererType != kUnityGfxRendererPS5NGGC)
{
return;
}
s_GraphicsPS5 = s_UnityInterfaces->Get<IUnityGraphicsPS5>();
s_GraphicsAgcPS5 = s_UnityInterfaces->Get<IUnityGraphicsAgcPS5>();
if (s_GraphicsPS5 == nullptr && s_GraphicsAgcPS5 == nullptr)
{
UNITY_LOG_ERROR(s_Log, "Could not obtain PS5 Graphics interface!");
return;
}
break;
}
case kUnityGfxDeviceEventShutdown:
{
s_GraphicsPS5 = nullptr;
s_GraphicsAgcPS5 = nullptr;
s_RendererType = kUnityGfxRendererNull;
break;
}
case kUnityGfxDeviceEventBeforeReset:
{
break;
}
case kUnityGfxDeviceEventAfterReset:
{
break;
}
};
}
extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_Init()
{
if (s_Log == nullptr || s_Graphics == nullptr)
{
// Plugin was not loaded correctly, cannot log an error message here
return INT32_MIN;
}
// Check if we're running on PS5 Pro
if (!sceKernelIsTrinityMode())
{
UNITY_LOG_ERROR(s_Log, "Kernel is not running in Trinity mode, PSML is not supported!");
return -1;
}
// Load PSML module
if (sceSysmoduleIsLoaded(SCE_SYSMODULE_PSML) != SCE_SYSMODULE_LOADED)
{
int res = sceSysmoduleLoadModule(SCE_SYSMODULE_PSML);
if (res < SCE_OK)
{
std::stringstream msg;
msg << "Failed to load PSML sysmodule, error code = " << res;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return res;
}
}
// Initialize MFSR
int res = initMfsr();
if (res != SCE_OK && res != SCE_PSML_MFSR_ERROR_ALREADY_INITIALIZED)
{
std::stringstream msg;
msg << "Failed to initialize MFSR, error code = " << res;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return res;
}
if (s_mfsrInitialized)
{
return SCE_OK;
}
// Set up MFSR shared resources
{
// Get required physical memory blocks sizeAlign for initializing MFSR shared resources
MfsrSharedResourcesInitParameters mfsrSharedResourcesInitParameters;
mfsrSharedResourcesInitParameters.init();
mfsrSharedResourcesInitParameters.m_profile = MfsrProfile::kQuality;
MfsrSharedResourcesInitRequirement mfsrSharedResourcesInitRequirement;
getMfsrSharedResourcesInitRequirement(&mfsrSharedResourcesInitRequirement, &mfsrSharedResourcesInitParameters);
// Allocate physical memory blocks for MFSR shared resource and setup shared resources init param
s_mfsrSharedResourcesMemoryBlocks = new MfsrPhysicalMemoryBlock[mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockCount];
size_t blockSize = mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockSize;
size_t blockAlign = mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockAlignment;
s_mfsrSharedResourcesMemorySize = mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockCount * blockSize;
sceKernelAllocateMainDirectMemory(s_mfsrSharedResourcesMemorySize, blockAlign, SCE_KERNEL_MTYPE_C_SHARED, &s_mfsrSharedResourcesMemoryAddress);
for (uint32_t i = 0; i < mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockCount; i++)
{
s_mfsrSharedResourcesMemoryBlocks[i].m_size = blockSize;
s_mfsrSharedResourcesMemoryBlocks[i].m_offset = s_mfsrSharedResourcesMemoryAddress + blockSize * i;
}
mfsrSharedResourcesInitParameters.m_physicalMemoryBlocks = s_mfsrSharedResourcesMemoryBlocks;
mfsrSharedResourcesInitParameters.m_physicalMemoryBlockCount = mfsrSharedResourcesInitRequirement.m_physicalMemoryBlockCount;
// Create MFSR shared resources with the memory
createMfsrSharedResources(&s_mfsrSharedResources, &mfsrSharedResourcesInitParameters);
}
s_mfsrInitialized = true;
UNITY_LOG(s_Log, "PSSR plugin initialized");
return SCE_OK;
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_Release()
{
s_mfsrInitialized = false;
// Destroy the MFSR shared resources
if (s_mfsrSharedResources != nullptr)
{
releaseMfsrSharedResources(s_mfsrSharedResources);
s_mfsrSharedResources = nullptr;
}
// Free the memory used for MFSR shared resource data
if (s_mfsrSharedResourcesMemoryAddress != 0)
{
sceKernelReleaseDirectMemory(s_mfsrSharedResourcesMemoryAddress, s_mfsrSharedResourcesMemorySize);
s_mfsrSharedResourcesMemoryAddress = 0;
s_mfsrSharedResourcesMemorySize = 0;
}
if (s_mfsrSharedResourcesMemoryBlocks != nullptr)
{
delete[] s_mfsrSharedResourcesMemoryBlocks;
s_mfsrSharedResourcesMemoryBlocks = nullptr;
}
}
typedef struct pssr_init_params_s
{
uint32_t contextIndex;
uint32_t displayWidth;
uint32_t displayHeight;
uint32_t maxRenderWidth;
uint32_t maxRenderHeight;
uint32_t autoKeepCopies;
} pssr_init_params_t;
typedef struct pssr_dispatch_params_s
{
uint32_t contextIndex;
sce::Agc::Core::Texture* color;
sce::Agc::Core::Texture* depth;
sce::Agc::Core::Texture* prevDepth;
sce::Agc::Core::Texture* motionVectors;
sce::Agc::Core::Texture* prevMotionVectors;
sce::Agc::Core::Texture* exposure;
sce::Agc::Core::Texture* reactiveMask;
sce::Agc::Core::Texture* outputColor;
uint32_t renderWidth;
uint32_t renderHeight;
Vector2f jitter;
Vector2f motionVectorScale;
Matrix4f camProjectionNoJitter;
Vector3f camForward;
Vector3f camUp;
Vector3f camRight;
Vector3d camPosition;
float camNear;
float camFar;
float preExposure;
uint32_t resetHistory;
MfsrOptionFlags flags;
} pssr_dispatch_params_t;
typedef struct pssr_destroy_params_s
{
uint32_t contextIndex;
} pssr_destroy_params_t;
typedef struct pssr_capture_params_s
{
uint32_t contextIndex;
uint8_t frameNum;
} pssr_capture_params_t;
static bool IsInitialized()
{
if (!s_mfsrInitialized)
return false;
if (s_RendererType == kUnityGfxRendererPS5 && s_GraphicsPS5 == nullptr)
return false;
if (s_RendererType == kUnityGfxRendererPS5NGGC && s_GraphicsAgcPS5 == nullptr)
return false;
return true;
}
extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_CreateContext(const pssr_init_params_t* params, Core::Texture** outputColorTexture)
{
if (!IsInitialized())
{
UNITY_LOG_ERROR(s_Log, "PSSR plugin is not initialized properly");
return -1;
}
if (params->contextIndex < 0 || params->contextIndex >= MaxNumContexts)
{
std::stringstream msg;
msg << "Invalid PSSR context index: " << params->contextIndex;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return -1;
}
PssrContext& context = s_contexts[params->contextIndex];
MfsrContextInitParameters initParams = {};
initParams.init();
initParams.m_outputColorWidth = params->displayWidth;
initParams.m_outputColorHeight = params->displayHeight;
initParams.m_sharedResources = s_mfsrSharedResources;
MfsrKeepCopyTextureSpec depthCopySpec = {}, mvCopySpec = {};
if (params->autoKeepCopies)
{
// Keep a copy of the previous depth internally
depthCopySpec.m_width = params->maxRenderWidth;
depthCopySpec.m_height = params->maxRenderHeight;
depthCopySpec.m_bytesPerPixel = 4; // R32_SFloat
initParams.m_maxSizeDepthForKeepCopy = &depthCopySpec;
// Keep a copy of the previous motion vectors internally
mvCopySpec.m_width = params->maxRenderWidth;
mvCopySpec.m_height = params->maxRenderHeight;
mvCopySpec.m_bytesPerPixel = 4; // R16G16_SFloat
initParams.m_maxSizeMotionVectorsForKeepCopy = &mvCopySpec;
}
// Allocate memory used by this MFSR context
{
MfsrContextInitRequirement mfsrInitRequirement = {};
getMfsrContextInitRequirement(&mfsrInitRequirement, &initParams);
context.mfsrMemoryBlocks = new MfsrPhysicalMemoryBlock[mfsrInitRequirement.m_physicalMemoryBlockCount];
size_t size = mfsrInitRequirement.m_physicalMemoryBlockSize;
size_t align = mfsrInitRequirement.m_physicalMemoryBlockAlignment;
context.mfsrMemorySize = mfsrInitRequirement.m_physicalMemoryBlockCount * size;
sceKernelAllocateMainDirectMemory(context.mfsrMemorySize, align, SCE_KERNEL_MTYPE_C_SHARED, &context.mfsrMemoryPhysicalAddress);
for (uint32_t i = 0; i < mfsrInitRequirement.m_physicalMemoryBlockCount; i++)
{
context.mfsrMemoryBlocks[i].m_size = size;
context.mfsrMemoryBlocks[i].m_offset = context.mfsrMemoryPhysicalAddress + mfsrInitRequirement.m_physicalMemoryBlockSize * i;
}
initParams.m_sharedResources = s_mfsrSharedResources;
initParams.m_physicalMemoryBlocks = context.mfsrMemoryBlocks;
initParams.m_physicalMemoryBlockCount = mfsrInitRequirement.m_physicalMemoryBlockCount;
}
// Set up output color texture with the correct specifications (k11_11_10Float with tile mode kStandard256B)
if (outputColorTexture != nullptr)
{
Core::TextureSpec texSpec;
texSpec.init();
texSpec.setAllowNullptr(true);
texSpec.m_width = params->displayWidth;
texSpec.m_height = params->displayHeight;
texSpec.m_format = { Core::TypedFormat::k11_11_10Float, Core::Swizzle::kRGB1_R3S34 };
texSpec.setTileMode(Core::Texture::TileMode::kStandard256B);
SizeAlign sizeAlign = Core::getSize(&texSpec);
if (s_GraphicsPS5 != nullptr)
{
texSpec.m_dataAddress = s_GraphicsPS5->AllocateGPUMemory(sizeAlign.m_size, MfsrAlignment::kOutputTexture);
}
else if (s_GraphicsAgcPS5 != nullptr)
{
texSpec.m_dataAddress = s_GraphicsAgcPS5->AllocateGPUMemory(sizeAlign.m_size, MfsrAlignment::kOutputTexture);
}
int res = Core::initialize(&context.outputColorTexture, &texSpec);
if (res != SCE_OK)
{
std::stringstream msg;
msg << "Failed to create MFSR output color texture, error code = " << res;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return res;
}
*outputColorTexture = &context.outputColorTexture;
}
// Set up command buffer for NGGC
if (s_RendererType == kUnityGfxRendererPS5NGGC && s_GraphicsAgcPS5 != nullptr)
{
const size_t agcContextSize = 128 * 1024;
context.agcContext.m_dcb.init(s_GraphicsAgcPS5->AllocateGPUMemory(agcContextSize, Alignment::kCommandBuffer), agcContextSize);
context.agcContext.m_bdr.init(&context.agcContext.m_dcb, &context.agcContext.m_dcb);
context.agcContext.m_sb.init(256, &context.agcContext.m_dcb, &context.agcContext.m_dcb);
}
// Finally, create the actual MFSR context
int res = createMfsrContext(&context.mfsrContext, &initParams);
if (res != SCE_OK)
{
std::stringstream msg;
msg << "Failed to create MFSR context, error code = " << res;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return res;
}
UNITY_LOG(s_Log, "Created PSSR context");
return SCE_OK;
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_DestroyContext(uint32_t contextIndex)
{
if (!IsInitialized())
{
UNITY_LOG_ERROR(s_Log, "PSSR plugin is not initialized properly");
return;
}
if (contextIndex < 0 || contextIndex >= MaxNumContexts)
{
std::stringstream msg;
msg << "Invalid PSSR context index: " << contextIndex;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return;
}
PssrContext& context = s_contexts[contextIndex];
// Destroy the MFSR context
if (context.mfsrContext != nullptr)
{
releaseMfsrContext(context.mfsrContext);
context.mfsrContext = nullptr;
}
// Destroy the NGGC command buffer
if (s_GraphicsAgcPS5 != nullptr && context.agcContext.m_dcb.m_bottom != nullptr)
{
s_GraphicsAgcPS5->ReleaseGPUMemory(context.agcContext.m_dcb.m_bottom);
context.agcContext.m_dcb.clear();
}
// Destroy the output color texture
if (context.outputColorTexture.getDataAddress())
{
if (s_GraphicsPS5 != nullptr)
{
s_GraphicsPS5->ReleaseGPUMemory(context.outputColorTexture.getDataAddress());
}
else if (s_GraphicsAgcPS5 != nullptr)
{
s_GraphicsAgcPS5->ReleaseGPUMemory(context.outputColorTexture.getDataAddress());
}
context.outputColorTexture.init();
}
// Free the memory used for MFSR context data
if (context.mfsrMemoryPhysicalAddress != 0)
{
sceKernelReleaseDirectMemory(context.mfsrMemoryPhysicalAddress, context.mfsrMemorySize);
context.mfsrMemoryPhysicalAddress = 0;
context.mfsrMemorySize = 0;
}
if (context.mfsrMemoryBlocks != nullptr)
{
delete[] context.mfsrMemoryBlocks;
context.mfsrMemoryBlocks = nullptr;
}
UNITY_LOG(s_Log, "Destroyed PSSR context");
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_Dispatch(const pssr_dispatch_params_t* params)
{
if (!IsInitialized())
{
UNITY_LOG_ERROR(s_Log, "PSSR plugin is not initialized properly");
return;
}
if (params->contextIndex < 0 || params->contextIndex >= MaxNumContexts)
{
std::stringstream msg;
msg << "Invalid PSSR context index: " << params->contextIndex;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return;
}
PssrContext& context = s_contexts[params->contextIndex];
if (context.mfsrContext == nullptr)
return;
// How we obtain a command buffer to dispatch to depends on which graphics API we're using in Unity
sce::Agc::DrawCommandBuffer* cmd = nullptr;
if (s_RendererType == kUnityGfxRendererPS5)
{
auto* gfxc = (sce::Agc::Gnmp::LightweightGfxContext*)s_GraphicsPS5->GetGfxContext();
cmd = &gfxc->m_agcCtx.m_dcb;
}
else if (s_RendererType == kUnityGfxRendererPS5NGGC)
{
Core::BasicContext& ctx = context.agcContext.reset();
cmd = &ctx.m_dcb;
}
cmd->pushMarker("Dispatch MFSR");
DispatchMfsrParameters dispatchParams = {};
dispatchParams.init();
dispatchParams.m_outputColor = params->outputColor;
dispatchParams.m_color = params->color;
dispatchParams.m_motionVectors = params->motionVectors;
dispatchParams.m_prevDepth = params->prevDepth;
dispatchParams.m_depth = params->depth;
dispatchParams.m_exposure = params->exposure;
dispatchParams.m_reactiveMask = params->reactiveMask;
dispatchParams.m_prevMotionVectors = params->prevMotionVectors;
dispatchParams.m_preExposure = params->preExposure;
dispatchParams.m_projectionNoJitter = params->camProjectionNoJitter;
dispatchParams.m_camForward = params->camForward;
dispatchParams.m_camUp = params->camUp;
dispatchParams.m_camRight = params->camRight;
dispatchParams.m_camPosD = params->camPosition;
dispatchParams.m_nearZ = params->camNear;
dispatchParams.m_farZ = params->camFar;
dispatchParams.m_renderWidth = params->renderWidth;
dispatchParams.m_renderHeight = params->renderHeight;
dispatchParams.m_jitter = params->jitter;
dispatchParams.m_motionVectorScale = params->motionVectorScale;
dispatchParams.m_motionVectorGamma = 1.0f;
dispatchParams.m_reset = params->resetHistory != 0;
dispatchParams.m_flags = params->flags;
dispatchMfsr(context.mfsrContext, cmd, &dispatchParams);
cmd->popMarker();
if (s_RendererType == kUnityGfxRendererPS5NGGC)
{
s_GraphicsAgcPS5->SubmitGraphics(cmd->getSubmitPointer(), cmd->getSubmitSize());
}
}
extern "C" int32_t UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API PSSR_RequestCapture(uint32_t contextIndex, uint8_t frameNum)
{
if (!IsInitialized())
{
UNITY_LOG_ERROR(s_Log, "PSSR plugin is not initialized properly");
return -1;
}
if (contextIndex < 0 || contextIndex >= MaxNumContexts)
{
std::stringstream msg;
msg << "Invalid PSSR context index: " << contextIndex;
UNITY_LOG_ERROR(s_Log, msg.str().c_str());
return -1;
}
PssrContext& context = s_contexts[contextIndex];
if (context.mfsrContext == nullptr)
return -1;
if (isMfsrCaptureInProgress(context.mfsrContext))
{
UNITY_LOG_WARNING(s_Log, "PSSR capture already in progress");
return -1;
}
return requestMfsrCapture(context.mfsrContext, frameNum);
}
// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void* data)
{
// User rendering code
switch (eventID)
{
case 0: // Create PSSR context
{
auto* params = (pssr_init_params_t*)data;
PSSR_CreateContext(params, nullptr);
break;
}
case 1: // Execute PSSR
{
auto* params = (pssr_dispatch_params_t*)data;
PSSR_Dispatch(params);
break;
}
case 2: // Destroy PSSR context
{
auto* params = (pssr_destroy_params_t*)data;
PSSR_DestroyContext(params->contextIndex);
break;
}
case 3: // Request PSSR capture
{
auto* params = (pssr_capture_params_t*)data;
PSSR_RequestCapture(params->contextIndex, params->frameNum);
break;
}
}
}

13
Packages/com.ww1gameseries.pssr/package.json

@ -0,0 +1,13 @@
{
"name": "com.ww1gameseries.pssr",
"version": "1.0.0",
"author": "WW1 Game Series",
"unity": "2022.3",
"displayName": "PSSR Upscaler Plugin",
"description": "Provides a native plugin for the PS5 Pro's PSSR upscaling technology",
"keywords": [
"ps5",
"playstation"
],
"dependencies": {}
}

7
Packages/com.ww1gameseries.pssr/package.json.meta

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1eef1819b5808e94e9a9d4de243456bb
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

6
Packages/packages-lock.json

@ -179,6 +179,12 @@
},
"url": "https://packages.unity.com"
},
"com.ww1gameseries.pssr": {
"version": "file:com.ww1gameseries.pssr",
"depth": 0,
"source": "embedded",
"dependencies": {}
},
"fidelityfx.fsr": {
"version": "file:fidelityfx.fsr",
"depth": 0,

Loading…
Cancel
Save