diff --git a/.gitignore b/.gitignore index b57860d5..803ea27f 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ UnityProject/Logs PluginSource/build PluginSource/projects/Android/libs/* PluginSource/projects/Android/obj/* +PluginSource/source/*.o diff --git a/PluginSource/projects/GNUMake/Makefile b/PluginSource/projects/GNUMake/Makefile index bf23155d..ceb189bc 100644 --- a/PluginSource/projects/GNUMake/Makefile +++ b/PluginSource/projects/GNUMake/Makefile @@ -7,7 +7,7 @@ OBJS = ${SRCS:.cpp=.o} UNITY_DEFINES = -DSUPPORT_OPENGL_UNIFIED=1 -DSUPPORT_VULKAN=1 -DUNITY_LINUX=1 CXXFLAGS = $(UNITY_DEFINES) -O2 -fPIC LDFLAGS = -shared -rdynamic -LIBS = +LIBS = -lGL PLUGIN_SHARED = libRenderingPlugin.so CXX ?= g++ diff --git a/PluginSource/projects/QNX/Makefile b/PluginSource/projects/QNX/Makefile new file mode 100644 index 00000000..0a0b112f --- /dev/null +++ b/PluginSource/projects/QNX/Makefile @@ -0,0 +1,48 @@ +# UNITY_QNX_TARGET_LIB allows to specify the path to the QNX target libraries +# e.g. for imx8qm, use "~/qnx710/target/qnx7/aarch64le/usr/lib/graphics/iMX8QM/" +UNITY_QNX_TARGET_LIB ?= $(QNX_TARGET)/aarch64le/usr/lib + +# UNITY_QNX_GLES2_LIB allows to link against a device/driver-specific library +# e.g. for imx8qm, use "GLESv2_viv" +UNITY_QNX_GLES2_LIB ?= GLESv2 + +SRCDIR = ../../source +SRCS = $(SRCDIR)/RenderingPlugin.cpp \ +$(SRCDIR)/RenderAPI.cpp \ +$(SRCDIR)/RenderAPI_OpenGLCoreES.cpp +OBJS = ${SRCS:.cpp=.o} +UNITY_DEFINES = -DUNITY_QNX=1 +CXXFLAGS = $(UNITY_DEFINES) -O2 -fPIC +LDFLAGS = -shared -rdynamic -static-libstdc++ -Wl,-soname,RenderingPlugin -Wl,-L$(UNITY_QNX_TARGET_LIB) -Wl,-l$(UNITY_QNX_GLES2_LIB) +LIBS = +PLUGIN_SHARED = libRenderingPlugin.so +CXX = ntoaarch64-g++ + +ifeq (, $(shell echo $(QNX_TARGET))) +$(error "QNX_TARGET is not set.") +endif + +ifeq (, $(shell echo $(QNX_HOST))) +$(error "QNX_HOST is not set.") +endif + +# Check if the CXX variable is set to a valid compiler +ifeq (, $(shell which $(CXX))) +$(error "No $(CXX) in PATH. Did you set '$$QNX_HOST/usr/bin' in your PATH?") +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: clean shared + +cleanobjs: + rm -f $(OBJS) + +cleanlib: + rm -f $(PLUGIN_SHARED) + +clean: cleanobjs cleanlib + +shared: $(OBJS) + $(CXX) $(LDFLAGS) -o $(PLUGIN_SHARED) $(OBJS) $(LIBS) diff --git a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.sln b/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.sln deleted file mode 100644 index 11fc4e6f..00000000 --- a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingPlugin", "RenderingPlugin.vcxproj", "{6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|ARM = Release|ARM - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|ARM.ActiveCfg = Debug|ARM - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|ARM.Build.0 = Debug|ARM - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|Win32.ActiveCfg = Debug|Win32 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|Win32.Build.0 = Debug|Win32 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|x64.ActiveCfg = Debug|x64 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Debug|x64.Build.0 = Debug|x64 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|ARM.ActiveCfg = Release|ARM - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|ARM.Build.0 = Release|ARM - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|Win32.ActiveCfg = Release|Win32 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|Win32.Build.0 = Release|Win32 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|x64.ActiveCfg = Release|x64 - {6C7AE7F4-BDCA-4E9A-81C8-75F5E138AA54}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj b/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj deleted file mode 100644 index fefa9331..00000000 --- a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj +++ /dev/null @@ -1,367 +0,0 @@ - - - - - Debug - ARM - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - Win32 - - - Release - x64 - - - - - - - - true - true - true - true - true - true - - - - - - - - - - - - - - - - true - true - true - true - true - true - - - - - {6c7ae7f4-bdca-4e9a-81c8-75f5e138aa54} - DynamicLibrary - RenderingPlugin - RenderingPlugin - en-US - 14.0 - true - Windows Store - 10.0.10586.0 - 10.0.10586.0 - 10.0 - - - - DynamicLibrary - true - - - DynamicLibrary - true - - - DynamicLibrary - true - - - DynamicLibrary - false - true - - - DynamicLibrary - false - true - - - DynamicLibrary - false - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - false - false - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1;%(ClCompile.PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - NotUsing - false - WINDOWS_UWP;UNITY_METRO;_WINDLL;%(PreprocessorDefinitions) - - - Console - false - false - ../../source/RenderingPlugin.def - - - SETLOCAL - -if "$(SolutionName)" == "RenderingPlugin" ( - set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\ -) else ( - set TARGET_PLUGIN_PATH=$(SolutionDir)$(SolutionName)\ -) - -echo Target Plugin Path is %TARGET_PLUGIN_PATH% - -mkdir "%TARGET_PLUGIN_PATH%Plugins" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP" -mkdir "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)" -copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%Plugins\Metro\UWP\$(PlatformShortName)\$(TargetFileName)" - -ENDLOCAL - - - - - - - diff --git a/PluginSource/projects/VisualStudio2015/RenderingPlugin.sln b/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.sln similarity index 100% rename from PluginSource/projects/VisualStudio2015/RenderingPlugin.sln rename to PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.sln diff --git a/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj b/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj new file mode 100644 index 00000000..13036483 --- /dev/null +++ b/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj @@ -0,0 +1,251 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + $(VULKAN_SDK)\Include + $(VULKAN_SDK)\Include + + + + + + + + + + true + true + true + true + + + + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C} + RenderingPlugin + Win32Proj + 10.0 + + + + DynamicLibrary + v143 + Unicode + + + DynamicLibrary + v143 + Unicode + + + DynamicLibrary + v143 + Unicode + + + DynamicLibrary + Unicode + v143 + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>12.0.30501.0 + + + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(IncludePath) + + + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(IncludePath) + + + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(IncludePath) + + + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\build\uwp\$(Platform)\$(Configuration)\ + $(IncludePath) + + + + GLEW_STATIC;WIN32 + + Level3 + stdcpp17 + MultiThreadedDLL + true + + + opengl32.lib;d3d12.lib + true + Windows + ../../source/RenderingPlugin.def + + + SETLOCAL + +if "$(PlatformShortName)" == "x86" ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x86 +) else ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x64 +) +echo Target Plugin Path is %TARGET_PLUGIN_PATH% +copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%\$(TargetFileName)" + +ENDLOCAL + + + + + + GLEW_STATIC;WIN32 + + + Level3 + stdcpp17 + MultiThreadedDLL + true + + + opengl32.lib;d3d12.lib + true + Windows + ../../source/RenderingPlugin.def + + + SETLOCAL + +if "$(PlatformShortName)" == "x86" ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x86 +) else ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x64 +) +echo Target Plugin Path is %TARGET_PLUGIN_PATH% +copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%\$(TargetFileName)" + +ENDLOCAL + + + + + + GLEW_STATIC;WIN32 + + Level3 + stdcpp17 + MultiThreadedDLL + true + + + opengl32.lib;d3d12.lib + true + Windows + ../../source/RenderingPlugin.def + + + SETLOCAL + +if "$(PlatformShortName)" == "x86" ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x86 +) else ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x64 +) +echo Target Plugin Path is %TARGET_PLUGIN_PATH% +copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%\$(TargetFileName)" + +ENDLOCAL + + + + + + GLEW_STATIC;WIN32 + + + Level3 + stdcpp17 + MultiThreadedDLL + true + + + opengl32.lib;d3d12.lib + true + Windows + ../../source/RenderingPlugin.def + + + SETLOCAL + +if "$(PlatformShortName)" == "x86" ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x86 +) else ( + set TARGET_PLUGIN_PATH=$(SolutionDir)..\..\..\UnityProject\Assets\Plugins\Metro\UWP\x64 +) +echo Target Plugin Path is %TARGET_PLUGIN_PATH% +copy /Y "$(TargetPath)" "%TARGET_PLUGIN_PATH%\$(TargetFileName)" + +ENDLOCAL + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj.filters b/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj.filters similarity index 95% rename from PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj.filters rename to PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj.filters index 0de05ac9..1b8c3c5b 100644 --- a/PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj.filters +++ b/PluginSource/projects/UWPVisualStudio2022/RenderingPlugin.vcxproj.filters @@ -49,6 +49,7 @@ + diff --git a/PluginSource/projects/VisualStudio2022/RenderingPlugin.sln b/PluginSource/projects/VisualStudio2022/RenderingPlugin.sln new file mode 100644 index 00000000..abf801d5 --- /dev/null +++ b/PluginSource/projects/VisualStudio2022/RenderingPlugin.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40418.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RenderingPlugin", "RenderingPlugin.vcxproj", "{F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Debug|Win32.Build.0 = Debug|Win32 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Debug|x64.ActiveCfg = Debug|x64 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Debug|x64.Build.0 = Debug|x64 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Release|Win32.ActiveCfg = Release|Win32 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Release|Win32.Build.0 = Release|Win32 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Release|x64.ActiveCfg = Release|x64 + {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj b/PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj similarity index 73% rename from PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj rename to PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj index fd6d842e..993ab16a 100644 --- a/PluginSource/projects/VisualStudio2015/RenderingPlugin.vcxproj +++ b/PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj @@ -44,6 +44,7 @@ + @@ -57,30 +58,28 @@ {F7CFEF5A-54BD-42E8-A59E-54ABAEB4EA9C} RenderingPlugin Win32Proj - 10.0.16299.0 + 10.0 DynamicLibrary - v141 + v143 Unicode - true DynamicLibrary - v141 + v143 Unicode - true DynamicLibrary - v141 + v143 Unicode DynamicLibrary - v141 Unicode + v143 @@ -104,40 +103,36 @@ $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ - true + $(IncludePath) - true $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ + $(IncludePath) $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ - false + $(IncludePath) - false $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ $(SolutionDir)..\..\build\$(Platform)\$(Configuration)\ + $(IncludePath) - Disabled - GLEW_STATIC;WIN32;_DEBUG;_WINDOWS;_USRDLL;RENDERINGPLUGIN_EXPORTS;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug + GLEW_STATIC;WIN32 Level3 - EditAndContinue - ../../ + stdcpp17 + MultiThreadedDLL + true - opengl32.lib;%(AdditionalDependencies) + opengl32.lib;d3d12.lib true Windows - MachineX86 ../../source/RenderingPlugin.def @@ -157,18 +152,16 @@ ENDLOCAL - Disabled - GLEW_STATIC;WIN32;_DEBUG;_WINDOWS;_USRDLL;RENDERINGPLUGIN_EXPORTS;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug + GLEW_STATIC;WIN32 Level3 - ProgramDatabase - ../../ + stdcpp17 + MultiThreadedDLL + true - opengl32.lib;%(AdditionalDependencies) + opengl32.lib;d3d12.lib true Windows ../../source/RenderingPlugin.def @@ -190,23 +183,17 @@ ENDLOCAL - MaxSpeed - true - GLEW_STATIC;WIN32;NDEBUG;_WINDOWS;_USRDLL;RENDERINGPLUGIN_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - true + GLEW_STATIC;WIN32 Level3 - ProgramDatabase - ../../ + stdcpp17 + MultiThreadedDLL + true - opengl32.lib;%(AdditionalDependencies) + opengl32.lib;d3d12.lib true Windows - true - true - MachineX86 ../../source/RenderingPlugin.def @@ -226,23 +213,18 @@ ENDLOCAL - MaxSpeed - true - GLEW_STATIC;WIN32;NDEBUG;_WINDOWS;_USRDLL;RENDERINGPLUGIN_EXPORTS;%(PreprocessorDefinitions) - MultiThreaded - true + GLEW_STATIC;WIN32 Level3 - ProgramDatabase - ../../ + stdcpp17 + MultiThreadedDLL + true - opengl32.lib;%(AdditionalDependencies) + opengl32.lib;d3d12.lib true Windows - true - true ../../source/RenderingPlugin.def @@ -261,6 +243,9 @@ ENDLOCAL - - + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + \ No newline at end of file diff --git a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj.filters b/PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj.filters similarity index 64% rename from PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj.filters rename to PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj.filters index 5cb27e52..1b8c3c5b 100644 --- a/PluginSource/projects/UWPVisualStudio2015/RenderingPlugin.vcxproj.filters +++ b/PluginSource/projects/VisualStudio2022/RenderingPlugin.vcxproj.filters @@ -1,18 +1,8 @@  - - - - {0b7de993-622e-4614-b3bc-a6dd42480fbe} - - - - - - - - - + + + Unity @@ -31,11 +21,37 @@ Unity - - + + gl3w + + + gl3w + + + + + + + + + + + gl3w + + + + + {c01468d4-90d4-4d19-9a9b-ee2f1b5e9083} + + + {f00ad923-e825-43a2-b22c-b3380a3a8813} + - + + + + - + \ No newline at end of file diff --git a/PluginSource/projects/Xcode/RenderingPlugin.xcodeproj/project.pbxproj b/PluginSource/projects/Xcode/RenderingPlugin.xcodeproj/project.pbxproj index 08f683df..5c257d88 100644 --- a/PluginSource/projects/Xcode/RenderingPlugin.xcodeproj/project.pbxproj +++ b/PluginSource/projects/Xcode/RenderingPlugin.xcodeproj/project.pbxproj @@ -7,12 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 2B6899B81CF8396700C4BA4F /* RenderAPI_OpenGLCoreES.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B6899B01CF8396700C4BA4F /* RenderAPI_OpenGLCoreES.cpp */; }; 2B6899B91CF8396700C4BA4F /* RenderAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B6899B11CF8396700C4BA4F /* RenderAPI.cpp */; }; 2B6899BA1CF8396700C4BA4F /* RenderingPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B6899B31CF8396700C4BA4F /* RenderingPlugin.cpp */; }; 2B6899C91CF83DB000C4BA4F /* RenderingPlugin.bundle in Copy Bundle into Unity project */ = {isa = PBXBuildFile; fileRef = 8D576316048677EA00EA77CD /* RenderingPlugin.bundle */; }; 2B6899CB1CF8409A00C4BA4F /* RenderAPI_Metal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2B6899CA1CF8409A00C4BA4F /* RenderAPI_Metal.mm */; }; - 2BC2A8D5144C433D00D5EF79 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BC2A8D4144C433D00D5EF79 /* OpenGL.framework */; }; + 8A0E9E8B3022106C005CEB36 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A0E9E8A3022106C005CEB36 /* Metal.framework */; }; 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; }; /* End PBXBuildFile section */ @@ -33,9 +32,6 @@ /* Begin PBXFileReference section */ 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; 2B6899AB1CF8396700C4BA4F /* PlatformBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformBase.h; path = ../../source/PlatformBase.h; sourceTree = ""; }; - 2B6899AD1CF8396700C4BA4F /* RenderAPI_D3D11.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderAPI_D3D11.cpp; path = ../../source/RenderAPI_D3D11.cpp; sourceTree = ""; }; - 2B6899AE1CF8396700C4BA4F /* RenderAPI_D3D12.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderAPI_D3D12.cpp; path = ../../source/RenderAPI_D3D12.cpp; sourceTree = ""; }; - 2B6899B01CF8396700C4BA4F /* RenderAPI_OpenGLCoreES.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderAPI_OpenGLCoreES.cpp; path = ../../source/RenderAPI_OpenGLCoreES.cpp; sourceTree = ""; }; 2B6899B11CF8396700C4BA4F /* RenderAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderAPI.cpp; path = ../../source/RenderAPI.cpp; sourceTree = ""; }; 2B6899B21CF8396700C4BA4F /* RenderAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RenderAPI.h; path = ../../source/RenderAPI.h; sourceTree = ""; }; 2B6899B31CF8396700C4BA4F /* RenderingPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RenderingPlugin.cpp; path = ../../source/RenderingPlugin.cpp; sourceTree = ""; }; @@ -46,7 +42,7 @@ 2B6899C61CF839A600C4BA4F /* IUnityGraphicsMetal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IUnityGraphicsMetal.h; path = ../../source/Unity/IUnityGraphicsMetal.h; sourceTree = ""; }; 2B6899C71CF839A600C4BA4F /* IUnityInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IUnityInterface.h; path = ../../source/Unity/IUnityInterface.h; sourceTree = ""; }; 2B6899CA1CF8409A00C4BA4F /* RenderAPI_Metal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = RenderAPI_Metal.mm; path = ../../source/RenderAPI_Metal.mm; sourceTree = ""; }; - 2BC2A8D4144C433D00D5EF79 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 8A0E9E8A3022106C005CEB36 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; 8D576316048677EA00EA77CD /* RenderingPlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RenderingPlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -56,8 +52,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8A0E9E8B3022106C005CEB36 /* Metal.framework in Frameworks */, 8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */, - 2BC2A8D5144C433D00D5EF79 /* OpenGL.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -71,6 +67,7 @@ 089C167CFE841241C02AAC07 /* Resources */, 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, 19C28FB6FE9D52B211CA2CBB /* Products */, + 8A0E9E893022106C005CEB36 /* Frameworks */, ); name = RenderingPlugin; sourceTree = ""; @@ -79,7 +76,6 @@ isa = PBXGroup; children = ( 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */, - 2BC2A8D4144C433D00D5EF79 /* OpenGL.framework */, ); name = "External Frameworks and Libraries"; sourceTree = ""; @@ -97,10 +93,7 @@ children = ( 2B6899BC1CF8398200C4BA4F /* Unity */, 2B6899AB1CF8396700C4BA4F /* PlatformBase.h */, - 2B6899AD1CF8396700C4BA4F /* RenderAPI_D3D11.cpp */, - 2B6899AE1CF8396700C4BA4F /* RenderAPI_D3D12.cpp */, 2B6899CA1CF8409A00C4BA4F /* RenderAPI_Metal.mm */, - 2B6899B01CF8396700C4BA4F /* RenderAPI_OpenGLCoreES.cpp */, 2B6899B11CF8396700C4BA4F /* RenderAPI.cpp */, 2B6899B21CF8396700C4BA4F /* RenderAPI.h */, 2B6899B31CF8396700C4BA4F /* RenderingPlugin.cpp */, @@ -129,6 +122,14 @@ name = Unity; sourceTree = ""; }; + 8A0E9E893022106C005CEB36 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8A0E9E8A3022106C005CEB36 /* Metal.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -194,7 +195,6 @@ buildActionMask = 2147483647; files = ( 2B6899BA1CF8396700C4BA4F /* RenderingPlugin.cpp in Sources */, - 2B6899B81CF8396700C4BA4F /* RenderAPI_OpenGLCoreES.cpp in Sources */, 2B6899B91CF8396700C4BA4F /* RenderAPI.cpp in Sources */, 2B6899CB1CF8409A00C4BA4F /* RenderAPI_Metal.mm in Sources */, ); @@ -214,9 +214,10 @@ HEADER_SEARCH_PATHS = ../; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 12.0; + ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:rfc1034Identifier}"; PRODUCT_NAME = RenderingPlugin; - VALID_ARCHS = x86_64; WRAPPER_EXTENSION = bundle; }; name = Debug; @@ -231,9 +232,10 @@ HEADER_SEARCH_PATHS = ../; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + MACOSX_DEPLOYMENT_TARGET = 12.0; + ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.${PRODUCT_NAME:rfc1034Identifier}"; PRODUCT_NAME = RenderingPlugin; - VALID_ARCHS = x86_64; WRAPPER_EXTENSION = bundle; }; name = Release; @@ -244,8 +246,8 @@ ARCHS = "$(ARCHS_STANDARD)"; ENABLE_TESTABILITY = YES; GCC_OPTIMIZATION_LEVEL = 0; - MACOSX_DEPLOYMENT_TARGET = 10.11; - ONLY_ACTIVE_ARCH = YES; + MACOSX_DEPLOYMENT_TARGET = 12.0; + ONLY_ACTIVE_ARCH = NO; SDKROOT = macosx; SYMROOT = ../../build; }; @@ -255,9 +257,10 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 12.0; SDKROOT = macosx; SYMROOT = ../../build; + ONLY_ACTIVE_ARCH = NO; }; name = Release; }; diff --git a/PluginSource/source/PlatformBase.h b/PluginSource/source/PlatformBase.h index 9482d3fd..c9d4e8b3 100644 --- a/PluginSource/source/PlatformBase.h +++ b/PluginSource/source/PlatformBase.h @@ -28,7 +28,7 @@ #endif #elif defined(__ANDROID__) #define UNITY_ANDROID 1 -#elif defined(UNITY_METRO) || defined(UNITY_LINUX) || defined(UNITY_WEBGL) || defined (UNITY_EMBEDDED_LINUX) || defined (UNITY_EMBEDDED_LINUX_GL) +#elif defined(UNITY_METRO) || defined(UNITY_LINUX) || defined(UNITY_WEBGL) || defined (UNITY_EMBEDDED_LINUX) || defined (UNITY_EMBEDDED_LINUX_GL) || defined (UNITY_QNX) // these are defined externally #elif defined(__EMSCRIPTEN__) // this is already defined in Unity 5.6 @@ -47,11 +47,11 @@ #endif #elif UNITY_WIN #define SUPPORT_D3D11 1 // comment this out if you don't have D3D11 header/library files - #define SUPPORT_D3D12 1 // comment this out if you don't have D3D12 header/library files + #define SUPPORT_D3D12 0 // comment this out if you don't have D3D12 header/library files #define SUPPORT_OPENGL_UNIFIED 1 #define SUPPORT_OPENGL_CORE 1 #define SUPPORT_VULKAN 0 // Requires Vulkan SDK to be installed -#elif UNITY_IOS || UNITY_TVOS || UNITY_ANDROID || UNITY_WEBGL +#elif UNITY_ANDROID || UNITY_WEBGL #ifndef SUPPORT_OPENGL_ES #define SUPPORT_OPENGL_ES 1 #endif @@ -59,7 +59,7 @@ #ifndef SUPPORT_VULKAN #define SUPPORT_VULKAN 0 #endif -#elif UNITY_OSX || UNITY_LINUX +#elif UNITY_LINUX #define SUPPORT_OPENGL_UNIFIED 1 #define SUPPORT_OPENGL_CORE 1 #elif UNITY_EMBEDDED_LINUX @@ -68,6 +68,9 @@ #ifndef SUPPORT_VULKAN #define SUPPORT_VULKAN 0 #endif +#elif UNITY_QNX + #define SUPPORT_OPENGL_UNIFIED 1 + #define SUPPORT_OPENGL_ES 1 #endif #if UNITY_IOS || UNITY_TVOS || UNITY_OSX diff --git a/PluginSource/source/RenderAPI.cpp b/PluginSource/source/RenderAPI.cpp index 238b397f..6b18cede 100644 --- a/PluginSource/source/RenderAPI.cpp +++ b/PluginSource/source/RenderAPI.cpp @@ -2,7 +2,6 @@ #include "PlatformBase.h" #include "Unity/IUnityGraphics.h" - RenderAPI* CreateRenderAPI(UnityGfxRenderer apiType) { # if SUPPORT_D3D11 @@ -23,7 +22,7 @@ RenderAPI* CreateRenderAPI(UnityGfxRenderer apiType) # if SUPPORT_OPENGL_UNIFIED - if (apiType == kUnityGfxRendererOpenGLCore || apiType == kUnityGfxRendererOpenGLES20 || apiType == kUnityGfxRendererOpenGLES30) + if (apiType == kUnityGfxRendererOpenGLCore || apiType == kUnityGfxRendererOpenGLES30) { extern RenderAPI* CreateRenderAPI_OpenGLCoreES(UnityGfxRenderer apiType); return CreateRenderAPI_OpenGLCoreES(apiType); diff --git a/PluginSource/source/RenderAPI.h b/PluginSource/source/RenderAPI.h index b2387844..f2935ff8 100644 --- a/PluginSource/source/RenderAPI.h +++ b/PluginSource/source/RenderAPI.h @@ -6,7 +6,6 @@ struct IUnityInterfaces; - // Super-simple "graphics abstraction". This is nothing like how a proper platform abstraction layer would look like; // all this does is a base interface for whatever our plugin sample needs. Which is only "draw some triangles" // and "modify a texture" at this point. @@ -47,6 +46,41 @@ class RenderAPI virtual void* BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize) = 0; // End modifying vertex buffer data. virtual void EndModifyVertexBuffer(void* bufferHandle) = 0; + + // -------------------------------------------------------------------------- + // DX12 plugin specific functions + // -------------------------------------------------------------------------- + + // Draws to a texture that is created by the plugin + virtual void drawToPluginTexture() {} + + // Draws to a a unity RenderBuffer which can be set with + // setRenderTextureResource(). When the texture resource is not + // set with setRenderTextureResource() one is created by the plugin + virtual void drawToRenderTexture() {} + + // Returns the native resource pointer to either unity render buffer or + // to the resource created by the plugin (i.e ID3D12Resource* in case of DX12) + virtual void* getRenderTexture() { return nullptr; } + + // Sets the underlying resource to unity RenderBuffer + // see https://docs.unity3d.com/ScriptReference/RenderBuffer.html + // setting rb to nullptr is used to signal the plugin that the + // previously set RenderBuffer is no longer valid + virtual void setRenderTextureResource(UnityRenderBuffer rb) {} + + // This should return true when the plugin is used with the unity player + // and false when the editor is used. The editor uses multiple swap + // chains (for each window) so instead of choosing one of them nullptr is returned. + virtual bool isSwapChainAvailable() { return false; }; + + // These require the swap chain to be available to be functional. + // When the swap chain is not available these simply return 0 + + virtual unsigned int getPresentFlags() { return 0; } + virtual unsigned int getSyncInterval() { return 0; } + virtual unsigned int getBackbufferWidth() { return 0; } + virtual unsigned int getBackbufferHeight() { return 0; } }; diff --git a/PluginSource/source/RenderAPI_D3D12.cpp b/PluginSource/source/RenderAPI_D3D12.cpp index aabc3273..135b6516 100644 --- a/PluginSource/source/RenderAPI_D3D12.cpp +++ b/PluginSource/source/RenderAPI_D3D12.cpp @@ -5,268 +5,1666 @@ // Direct3D 12 implementation of RenderAPI. - #if SUPPORT_D3D12 #include +#include +#include #include +#include "d3dx12.h" #include "Unity/IUnityGraphicsD3D12.h" +#include +#include +#include +#include +#include + +#define ReturnOnFail(x, hr, OnFailureMsg, onFailureReturnValue) hr = x; if(FAILED(hr)){OutputDebugStringA(OnFailureMsg); return onFailureReturnValue;} + +#define D3D12_DEFAULT_HEAP_TRIANGLE_BUFFER_NAME L"Native Plugin Default Heap Triangle Vertex Buffer" +#define D3D12_UPLOAD_HEAP_TRIANGLE_BUFFER_NAME L"Native Plugin Upload Heap Triangle Vertex Buffer" +#define D3D12_UPLOAD_HEAP_TEXTURE_BUFFER_NAME L"Native Plugin Upload Heap Texture" +#define D3D12_UPLOAD_HEAP_VERTEX_BUFFER_NAME L"Native Plugin Upload Heap Vertex Buffer" +// Compiled from: +/* + cbuffer MyCB : register(b0) + { + float4x4 worldMatrix; + } + void VS(float3 pos : POSITION, float4 color : COLOR, out float4 ocolor : COLOR, out float4 opos : SV_Position) + { + opos = mul(worldMatrix, float4(pos, 1)); + ocolor = color; + } + float4 PS(float4 color : COLOR) : SV_TARGET + { + return color; + } + */ + + // using: + /* + dxc -T vs_6_0 -E VSMain -Fo vertex_shader .\shaders.hlsl -Qstrip_reflect -Qstrip_debug + dxc -T ps_6_0 -E PSMain -Fo pixel_shader .\shaders.hlsl -Qstrip_reflect -Qstrip_debug + */ + +const BYTE vertex_shader[] = +{ + 68,88,66,67,128,57,232,34,242,147,249,9,179,113,162,105,42,26,31, + 250,1,0,0,0,109,9,0,0,6,0,0,0,56,0,0,0,72,0,0, + 0,167,0,0,0,9,1,0,0,237,1,0,0,9,2,0,0,83,70,73, + 48,8,0,0,0,0,0,0,0,0,0,0,0,73,83,71,49,87,0,0, + 0,2,0,0,0,8,0,0,0,0,0,0,0,72,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,0,0,0,0,7,7,0,0,0,0,0, + 0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,3,0,0, + 0,1,0,0,0,15,15,0,0,0,0,0,0,80,79,83,73,84,73,79, + 78,0,67,79,76,79,82,0,79,83,71,49,90,0,0,0,2,0,0,0, + 8,0,0,0,0,0,0,0,72,0,0,0,0,0,0,0,0,0,0,0, + 3,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0, + 78,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,1,0,0,0, + 15,0,0,0,0,0,0,0,67,79,76,79,82,0,83,86,95,80,111,115, + 105,116,105,111,110,0,80,83,86,48,220,0,0,0,48,0,0,0,1,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255, + 255,255,1,0,0,0,2,2,0,2,2,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,1,0,0,0,24,0,0,0,2,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,24,0, + 0,0,0,80,79,83,73,84,73,79,78,0,67,79,76,79,82,0,67,79, + 76,79,82,0,0,0,1,0,0,0,0,0,0,0,16,0,0,0,1,0, + 0,0,0,0,0,0,1,0,67,0,3,0,0,0,10,0,0,0,0,0, + 0,0,1,1,68,0,3,0,0,0,16,0,0,0,0,0,0,0,1,0, + 68,0,3,2,0,0,0,0,0,0,0,0,0,0,1,1,68,3,3,4, + 0,0,240,0,0,0,240,0,0,0,240,0,0,0,0,0,0,0,1,0, + 0,0,2,0,0,0,4,0,0,0,8,0,0,0,72,65,83,72,20,0, + 0,0,0,0,0,0,104,176,13,123,21,10,21,217,124,92,148,133,249,234, + 46,114,68,88,73,76,92,7,0,0,96,0,1,0,215,1,0,0,68,88, + 73,76,0,1,0,0,16,0,0,0,68,7,0,0,66,67,192,222,33,12, + 0,0,206,1,0,0,11,130,32,0,2,0,0,0,19,0,0,0,7,129, + 35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4, + 139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50, + 82,136,72,144,20,32,67,70,136,165,0,25,50,66,228,72,14,144,145,34, + 196,80,65,81,129,140,225,131,229,138,4,41,70,6,81,24,0,0,8,0, + 0,0,27,140,224,255,255,255,255,7,64,2,168,13,132,240,255,255,255,255, + 3,32,109,48,134,255,255,255,255,31,0,9,168,0,73,24,0,0,3,0, + 0,0,19,130,96,66,32,76,8,6,0,0,0,0,137,32,0,0,35,0, + 0,0,50,34,72,9,32,100,133,4,147,34,164,132,4,147,34,227,132,161, + 144,20,18,76,138,140,11,132,164,76,16,104,35,0,37,0,20,102,0,230, + 8,192,96,142,0,41,198,32,132,20,66,166,24,128,16,82,6,161,163,134, + 203,159,176,135,144,124,110,163,138,149,152,252,226,182,17,49,198,24,84,238, + 25,46,127,194,30,66,242,67,160,25,22,2,5,171,16,138,48,66,173,20, + 131,140,49,232,205,17,4,197,96,164,16,18,73,14,4,12,35,16,67,18, + 212,123,14,71,154,22,0,115,168,201,55,49,110,67,129,165,155,10,4,0, + 0,0,19,20,114,192,135,116,96,135,54,104,135,121,104,3,114,192,135,13, + 175,80,14,109,208,14,122,80,14,109,0,15,122,48,7,114,160,7,115,32, + 7,109,144,14,113,160,7,115,32,7,109,144,14,120,160,7,115,32,7,109, + 144,14,113,96,7,122,48,7,114,208,6,233,48,7,114,160,7,115,32,7, + 109,144,14,118,64,7,122,96,7,116,208,6,230,16,7,118,160,7,115,32, + 7,109,96,14,115,32,7,122,48,7,114,208,6,230,96,7,116,160,7,118, + 64,7,109,224,14,120,160,7,113,96,7,122,48,7,114,160,7,118,64,7, + 67,158,0,0,0,0,0,0,0,0,0,0,0,134,60,6,16,0,1,0, + 0,0,0,0,0,0,12,121,16,32,0,4,0,0,0,0,0,0,0,24, + 242,52,64,0,12,0,0,0,0,0,0,0,48,228,121,128,0,8,0,0, + 0,0,0,0,0,96,200,35,1,1,48,0,0,0,0,0,0,0,64,22, + 8,0,14,0,0,0,50,30,152,20,25,17,76,144,140,9,38,71,198,4, + 67,34,37,48,2,80,12,5,24,80,6,229,80,30,84,74,98,4,160,12, + 10,161,8,8,207,0,80,30,75,65,16,248,128,15,248,0,2,129,64,0, + 0,0,121,24,0,0,87,0,0,0,26,3,76,144,70,2,19,196,49,32, + 195,27,67,129,147,75,179,11,163,43,75,1,137,113,185,113,129,113,153,193, + 201,177,1,65,129,145,137,49,195,49,155,41,139,73,217,16,4,19,4,194, + 152,32,16,199,6,97,32,38,8,4,178,65,24,12,10,118,115,27,6,196, + 32,38,8,152,68,96,130,64,36,27,16,66,89,8,98,96,128,13,65,179, + 129,0,0,7,152,32,100,211,134,0,154,32,8,0,5,171,41,34,80,79, + 83,73,84,73,79,78,19,132,162,153,32,20,206,134,128,152,32,20,207,4, + 129,80,38,8,196,178,65,200,180,13,11,65,85,214,101,13,24,97,109,44, + 134,158,152,158,164,38,8,5,52,65,32,152,13,66,246,109,88,134,174,178, + 46,107,240,6,11,12,54,8,92,24,76,16,138,104,195,66,116,149,117,141, + 193,224,17,22,24,112,153,178,250,130,122,155,75,163,75,123,115,219,176,12, + 101,80,97,151,55,120,131,5,6,27,4,50,48,131,13,131,24,156,1,176, + 161,144,38,52,120,128,42,108,108,118,109,46,105,100,101,110,116,83,130,160, + 10,25,158,139,93,153,220,92,218,155,219,148,128,104,66,134,231,98,23,198, + 102,87,38,55,37,48,234,144,225,185,204,161,133,145,149,201,53,189,145,149, + 177,77,9,144,50,100,120,46,114,101,115,111,117,114,99,101,115,83,2,167, + 14,25,158,139,93,90,217,93,18,217,20,93,24,93,217,148,0,170,67,134, + 231,82,230,70,39,151,7,245,150,230,70,55,55,37,64,3,0,0,121,24, + 0,0,76,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56, + 132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244, + 128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132, + 131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7, + 121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236, + 144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33, + 28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60, + 188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104, + 7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119, + 128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224, + 14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28, + 220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152, + 67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60, + 252,130,59,212,3,59,176,195,12,196,33,7,124,112,3,122,40,135,118,128, + 135,25,209,67,14,248,224,6,228,32,14,231,224,6,246,16,14,242,192,14, + 225,144,15,239,80,15,244,0,0,0,113,32,0,0,24,0,0,0,6,32, + 188,172,13,108,195,229,59,143,47,4,84,81,16,81,233,0,67,73,24,128, + 128,249,197,109,91,129,52,92,190,243,248,66,68,0,19,17,2,205,176,16, + 22,48,13,151,239,60,254,226,0,131,216,60,212,228,23,183,109,2,213,112, + 249,206,227,75,147,19,17,40,53,61,212,228,23,183,109,4,210,112,249,206, + 227,79,68,52,33,64,132,249,197,109,3,0,0,0,97,32,0,0,122,0, + 0,0,19,4,65,44,16,0,0,0,5,0,0,0,68,138,171,20,10,97, + 6,160,236,74,174,8,168,148,0,197,17,0,0,0,35,6,9,0,130,96, + 32,97,4,99,89,193,136,65,2,128,32,24,24,29,130,93,208,49,98,144, + 0,32,8,6,134,151,100,24,129,140,24,36,0,8,130,129,241,41,90,246, + 36,35,6,9,0,130,96,96,128,193,178,105,146,50,98,144,0,32,8,6, + 70,24,48,219,70,45,35,6,9,0,130,96,96,136,65,195,113,8,51,98, + 144,0,32,8,6,198,24,56,93,55,53,35,6,7,0,130,96,208,136,65, + 131,120,163,9,1,48,154,32,4,163,9,131,48,154,64,12,35,6,7,0, + 130,96,208,156,129,212,144,193,104,66,0,140,38,8,193,104,194,32,140,38, + 16,195,136,193,1,128,32,24,52,108,112,73,213,104,66,0,140,38,8,193, + 104,194,32,140,38,16,195,136,193,1,128,32,24,52,113,192,93,106,48,154, + 16,0,163,9,66,48,154,48,8,163,9,196,96,211,37,159,17,3,4,0, + 65,48,120,236,192,12,158,43,24,49,64,0,16,4,131,231,14,206,96,185, + 2,11,14,232,152,181,201,103,196,0,1,64,16,12,30,61,80,3,105,11, + 70,12,16,0,4,193,224,217,131,53,112,182,192,2,5,58,150,125,242,25, + 49,64,0,16,4,131,199,15,220,160,250,130,17,3,4,0,65,48,120,254, + 224,13,162,47,176,160,129,142,113,99,32,159,17,3,4,0,65,48,120,68, + 65,14,176,49,8,70,12,16,0,4,193,224,25,133,57,160,198,32,176,0, + 130,206,136,65,2,128,32,24,32,167,64,7,163,32,10,123,208,140,24,36, + 0,8,130,1,114,10,116,48,10,162,224,6,201,136,65,2,128,32,24,32, + 167,64,7,163,32,10,120,80,140,24,36,0,8,130,1,114,10,116,48,10, + 162,160,7,193,136,65,2,128,32,24,32,167,64,7,162,32,10,123,176,6, + 35,6,9,0,130,96,128,156,2,29,136,130,40,184,129,26,140,24,36,0, + 8,130,1,114,10,116,32,10,162,128,7,105,48,98,144,0,32,8,6,200, + 41,208,129,40,136,130,30,160,1,2,0,0,0,0 +}; + +const BYTE pixel_shader[] = +{ + 68,88,66,67,155,38,61,235,152,175,36,0,5,163,174,225,114,25,46, + 165,1,0,0,0,48,6,0,0,6,0,0,0,56,0,0,0,72,0,0, + 0,126,0,0,0,184,0,0,0,64,1,0,0,92,1,0,0,83,70,73, + 48,8,0,0,0,0,0,0,0,0,0,0,0,73,83,71,49,46,0,0, + 0,1,0,0,0,8,0,0,0,0,0,0,0,40,0,0,0,0,0,0, + 0,0,0,0,0,3,0,0,0,0,0,0,0,15,15,0,0,0,0,0, + 0,67,79,76,79,82,0,79,83,71,49,50,0,0,0,1,0,0,0,8, + 0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,64,0,0,0,3, + 0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,83,86,95,84,97, + 114,103,101,116,0,80,83,86,48,128,0,0,0,48,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255, + 255,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,8,0,0,0,0,67,79,76,79,82,0, + 0,1,0,0,0,0,0,0,0,16,0,0,0,1,0,0,0,0,0,0, + 0,1,0,68,0,3,2,0,0,0,0,0,0,0,0,0,0,1,0,68, + 16,3,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,8,0,0, + 0,72,65,83,72,20,0,0,0,0,0,0,0,12,2,178,107,86,235,87, + 236,39,12,117,190,13,71,209,140,68,88,73,76,204,4,0,0,96,0,0, + 0,51,1,0,0,68,88,73,76,0,1,0,0,16,0,0,0,180,4,0, + 0,66,67,192,222,33,12,0,0,42,1,0,0,11,130,32,0,2,0,0, + 0,19,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132, + 12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50, + 20,56,8,24,75,10,50,66,136,72,144,20,32,67,70,136,165,0,25,50, + 66,228,72,14,144,17,34,196,80,65,81,129,140,225,131,229,138,4,33,70, + 6,81,24,0,0,6,0,0,0,27,140,224,255,255,255,255,7,64,2,168, + 13,132,240,255,255,255,255,3,32,1,0,0,0,73,24,0,0,2,0,0, + 0,19,130,96,66,32,0,0,0,137,32,0,0,15,0,0,0,50,34,8, + 9,32,100,133,4,19,34,164,132,4,19,34,227,132,161,144,20,18,76,136, + 140,11,132,132,76,16,48,35,0,37,0,138,25,128,57,2,48,152,35,64, + 138,49,68,84,68,86,12,32,162,26,194,129,128,52,32,0,0,19,20,114, + 192,135,116,96,135,54,104,135,121,104,3,114,192,135,13,175,80,14,109,208, + 14,122,80,14,109,0,15,122,48,7,114,160,7,115,32,7,109,144,14,113, + 160,7,115,32,7,109,144,14,120,160,7,115,32,7,109,144,14,113,96,7, + 122,48,7,114,208,6,233,48,7,114,160,7,115,32,7,109,144,14,118,64, + 7,122,96,7,116,208,6,230,16,7,118,160,7,115,32,7,109,96,14,115, + 32,7,122,48,7,114,208,6,230,96,7,116,160,7,118,64,7,109,224,14, + 120,160,7,113,96,7,122,48,7,114,160,7,118,64,7,67,158,0,0,0, + 0,0,0,0,0,0,0,0,134,60,6,16,0,1,0,0,0,0,0,0, + 0,12,121,16,32,0,4,0,0,0,0,0,0,0,200,2,1,11,0,0, + 0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,162,18,24,1, + 40,134,50,40,15,170,146,24,1,40,130,66,40,16,218,177,12,130,8,4, + 2,1,0,0,0,121,24,0,0,65,0,0,0,26,3,76,144,70,2,19, + 196,49,32,195,27,67,129,147,75,179,11,163,43,75,1,137,113,185,113,129, + 113,153,193,201,177,1,65,129,145,137,49,195,49,155,41,139,73,217,16,4, + 19,4,98,152,32,16,196,6,97,32,38,8,68,177,65,24,12,10,112,115, + 27,6,196,32,38,8,75,179,33,80,38,8,2,64,1,106,138,197,208,19, + 211,147,212,4,161,64,38,8,69,178,33,32,38,8,133,50,65,40,150,9, + 2,97,76,16,136,99,131,64,85,27,22,194,121,160,72,26,38,2,178,54, + 4,23,147,41,171,47,170,48,185,179,50,186,9,66,193,108,88,136,236,209, + 34,104,152,8,200,218,16,108,27,6,140,3,54,20,76,211,1,64,21,54, + 54,187,54,151,52,178,50,55,186,41,65,80,133,12,207,197,174,76,110,46, + 237,205,109,74,64,52,33,195,115,177,11,99,179,43,147,155,18,24,117,200, + 240,92,230,208,194,200,202,228,154,222,200,202,216,166,4,72,29,50,60,23, + 187,180,178,187,36,178,41,186,48,186,178,41,129,82,135,12,207,165,204,141, + 78,46,15,234,45,205,141,110,110,74,208,1,0,121,24,0,0,76,0,0, + 0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128, + 7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66, + 30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61, + 200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112, + 7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15, + 110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194, + 97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3, + 59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112, + 144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135, + 113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236, + 48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33, + 28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57, + 184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3, + 59,176,195,12,196,33,7,124,112,3,122,40,135,118,128,135,25,209,67,14, + 248,224,6,228,32,14,231,224,6,246,16,14,242,192,14,225,144,15,239,80, + 15,244,0,0,0,113,32,0,0,10,0,0,0,6,32,164,172,5,76,195, + 229,59,143,191,56,192,32,54,15,53,249,197,109,155,64,53,92,190,243,248, + 210,228,68,4,74,77,15,53,249,197,109,3,0,97,32,0,0,30,0,0, + 0,19,4,65,44,16,0,0,0,3,0,0,0,68,133,48,3,80,10,84, + 37,80,6,0,0,35,6,9,0,130,96,96,72,197,243,40,196,136,65,2, + 128,32,24,24,147,1,65,67,49,98,144,0,32,8,6,6,117,68,209,98, + 140,24,36,0,8,130,129,81,33,146,68,28,35,6,9,0,130,96,128,84, + 199,52,57,196,136,65,2,128,32,24,32,213,49,77,198,48,98,144,0,32, + 8,6,72,117,76,83,35,140,24,36,0,8,130,1,82,29,211,84,4,8, + 0,0,0,0,0 +}; + +struct Vec3 +{ + float x; + float y; + float z; +}; + +struct Vec4 +{ + float x; + float y; + float z; + float w; +}; + +struct Vertex +{ + Vec3 position; + Vec4 color; +}; + +static void handle_hr(HRESULT hr, const char* error = "") +{ + if (FAILED(hr)) + { + OutputDebugStringA(error); + std::cerr << error << "\n"; + abort(); + } +} + +struct D3D12MemoryObject +{ + ID3D12Resource* resource; + void* mapped; + D3D12_HEAP_TYPE heapType; + D3D12_RESOURCE_FLAGS resourceFlags; + UINT64 deviceMemorySize; +}; + +struct D3D12DefaultBufferMemoryObject +{ + D3D12MemoryObject uploadResource; + D3D12MemoryObject defaultResource; +}; class RenderAPI_D3D12 : public RenderAPI { public: - RenderAPI_D3D12(); - virtual ~RenderAPI_D3D12() { } + RenderAPI_D3D12(); + virtual ~RenderAPI_D3D12() override { } - virtual void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces); + virtual void ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces) override; + virtual bool GetUsesReverseZ() override { return true; } - virtual bool GetUsesReverseZ() { return true; } + //----------------------------------------------------------- + // These functions will be called from unity render thread, + // see kUnityD3D12GraphicsQueueAccess_DontCare - virtual void DrawSimpleTriangles(const float worldMatrix[16], int triangleCount, const void* verticesFloat3Byte4); + // Demonstrates how to use the CommandRecordingState + virtual void DrawSimpleTriangles(const float worldMatrix[16], int triangleCount, const void* verticesFloat3Byte4) override; - virtual void* BeginModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int* outRowPitch); - virtual void EndModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int rowPitch, void* dataPtr); + // These demonstrate how to submit work via ExecuteCommandList + virtual void* BeginModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int* outRowPitch) override; + virtual void EndModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int rowPitch, void* dataPtr) override; + virtual void* BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize) override; + virtual void EndModifyVertexBuffer(void* bufferHandle) override; + virtual void drawToRenderTexture() override; + //----------------------------------------------------------- - virtual void* BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize); - virtual void EndModifyVertexBuffer(void* bufferHandle); + //----------------------------------------------------------- + // These functions will be called from unity submission thread, + // see kUnityD3D12GraphicsQueueAccess_Allow -private: - UINT64 AlignPow2(UINT64 value); - UINT64 GetAlignedSize(int width, int height, int pixelSize, int rowPitch); - ID3D12Resource* GetUploadResource(UINT64 size); - void CreateResources(); - void ReleaseResources(); + // Demonstrates how to submit work to unity command queue + // directly via GetCommandQueue + virtual void drawToPluginTexture() override; + //----------------------------------------------------------- + + virtual void* getRenderTexture() override; + virtual void setRenderTextureResource(UnityRenderBuffer rb) override; + + virtual bool isSwapChainAvailable() override; + virtual unsigned int getPresentFlags() override; + virtual unsigned int getSyncInterval() override; + virtual unsigned int getBackbufferWidth() override; + virtual unsigned int getBackbufferHeight() override; private: - IUnityGraphicsD3D12v2* s_D3D12; - ID3D12Resource* s_D3D12Upload; - ID3D12CommandAllocator* s_D3D12CmdAlloc; - ID3D12GraphicsCommandList* s_D3D12CmdList; - UINT64 s_D3D12FenceValue = 0; - HANDLE s_D3D12Event = NULL; -}; + UINT64 align_pow2(UINT64 value); + + // Aligns texture to power of 2 boundary + UINT64 get_aligned_size(int width, int height, int pixelSize, int rowPitch); + + // Creates a new buffer on D3D12_HEAP_TYPE_UPLOAD when resource points to a nullptr. + // When resource points to a existing ID3D12Resource* we only check if it's big enough + // to hold the size, if not return false + bool get_upload_resource(ID3D12Resource** resource, UINT64 size, LPCWSTR name); + + // Creates dx12 buffer, if heapType allows CPU-access the resource will be also mapped + bool create_D3D12_buffer(size_t sizeInBytes, D3D12_HEAP_TYPE heapType, D3D12_RESOURCE_FLAGS resourceFlags, D3D12_RESOURCE_STATES initialResourceState, LPCWSTR resourceName, D3D12MemoryObject* buffer); + + // Creates two buffers; one on D3D12_HEAP_TYPE_UPLOAD and one on D3D12_HEAP_TYPE_DEFAULT, + // copies contents from initData to -> upload buffer -> default buffer + bool create_D3D12_default_buffer(ID3D12GraphicsCommandList* cmdLst, const void* initData, unsigned int bufferSizeInBytes, LPCWSTR uploadHeapResourceName, LPCWSTR defaultHeapResourceName, D3D12DefaultBufferMemoryObject& outMemoryObj); + + ID3D12PipelineState* create_triangle_pipeline(); + void create_triangle_input_layout(); + bool create_triangle_root_signature(); + + // Push buffer to deletion queue + void safe_destroy(unsigned long long frameNumber, const D3D12MemoryObject& buffer); + + // Processes deletion queue + void garbage_collect(bool force = false); + + // Destroy buffer without deletion queue + void immediate_destroy_d3d12_buffer(D3D12MemoryObject& buffer); + + // Creates and initializes all resources that are used across multiple frames + void initialize_and_create_resources(); + void release_resources(); + // Records commands that draw a single triangle to target_texture + void record_draw_cmd_list(ID3D12CommandAllocator* cmd_alloc, ID3D12GraphicsCommandList* cmd, ID3D12RootSignature* rootsig, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, D3D12_VERTEX_BUFFER_VIEW* vbview, const float* world_matrix, D3D12_VIEWPORT* viewport, ID3D12PipelineState* pso, ID3D12Resource* target_texture, D3D12_RESOURCE_STATES target_state); + + // Demonstrates how to submit work to unity worker thread via ExecuteCommandList API + UINT64 submit_cmd_to_unity_worker(ID3D12GraphicsCommandList* cmd, UnityGraphicsD3D12ResourceState* resource_states, int state_count); + + // Creates a texture that can be used as render target + ID3D12Resource* create_render_texture(); + void create_render_texture_rtv(ID3D12DescriptorHeap* desc_heap, ID3D12Resource* target, UINT offset); + + void transition_barrier(ID3D12GraphicsCommandList* cmd, ID3D12Resource* resource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after); + + // When unity frame fence changes we can be sure that previously submitted command lists have finished executing + void wait_for_unity_frame_fence(UINT64 fence_value); + + // Wait on any user provided fence + void wait_on_fence(UINT64 fence_value, ID3D12Fence* fence, HANDLE fence_event); + + DXGI_FORMAT typeless_fmt_to_typed(DXGI_FORMAT format); + + typedef std::vector D3D12Buffers; + typedef std::map DeleteQueue; + typedef std::unordered_map MappedVertexBuffers; + + IUnityGraphicsD3D12v7* s_d3d12; + + ID3D12Resource* s_upload_texture; + ID3D12Resource* s_upload_buffer; + ID3D12PipelineState* m_triangle_pso; + D3D12_INPUT_ELEMENT_DESC m_triangle_layout[2]; + ID3D12RootSignature* m_triangle_rootsig; + D3D12DefaultBufferMemoryObject m_triangle_vertex_buffer; + ID3D12DescriptorHeap* m_triangle_rtv_desc_heap; + ID3D12DescriptorHeap* m_triangle_dsv_desc_heap; + DeleteQueue m_DeleteQueue; + MappedVertexBuffers m_mapped_triangle_vertex_buffers; + + ID3D12DescriptorHeap* m_texture_rtv_desc_heap; + UINT m_texture_rtv_desc_size; + ID3D12Resource* m_render_texture_vertex_buffer; + D3D12_VERTEX_BUFFER_VIEW m_texture_vertex_buffer_view; + std::atomic m_render_texture; + std::atomic m_plugin_texture; + UINT m_texture_width = 256; + UINT m_texture_height = 256; + ID3D12CommandAllocator* m_render_texture_cmd_allocator; + ID3D12GraphicsCommandList* m_render_texture_cmd_list; + ID3D12CommandAllocator* m_plugin_texture_cmd_allocator; + ID3D12GraphicsCommandList* m_plugin_texture_cmd_list; + ID3DBlob* m_render_texture_root_blob; + ID3D12RootSignature* m_texture_root_sig; + ID3D12PipelineState* m_texture_pso; + std::atomic m_are_resources_initialized = false; + + UINT64 m_plugin_texture_fence_value = 0; + ID3D12Fence* m_plugin_texture_fence; + HANDLE m_plugin_texture_fence_event; + + ID3D12CommandAllocator* m_vertex_copy_cmd_allocator; + ID3D12GraphicsCommandList* m_vertex_copy_cmd_list; + + ID3D12CommandAllocator* m_texture_copy_cmd_allocator; + ID3D12GraphicsCommandList* m_texture_copy_cmd_list; + + UINT64 m_vertex_copy_fence = 0; + UINT64 m_texture_copy_fence = 0; + UINT64 m_render_texture_draw_fence = 0; + + HANDLE m_fence_event; + + bool m_is_render_texture_created_by_unity = false; +}; RenderAPI* CreateRenderAPI_D3D12() { - return new RenderAPI_D3D12(); + return new RenderAPI_D3D12(); } - const UINT kNodeMask = 0; - RenderAPI_D3D12::RenderAPI_D3D12() - : s_D3D12(NULL) - , s_D3D12Upload(NULL) - , s_D3D12CmdAlloc(NULL) - , s_D3D12CmdList(NULL) - , s_D3D12FenceValue(0) - , s_D3D12Event(NULL) + : s_d3d12(NULL) + , s_upload_texture(NULL) + , s_upload_buffer(NULL) + , m_triangle_pso(NULL) + , m_triangle_rootsig(NULL) + , m_triangle_rtv_desc_heap(NULL) + , m_triangle_dsv_desc_heap(NULL) + , m_texture_rtv_desc_heap(NULL) + , m_texture_rtv_desc_size(NULL) + , m_render_texture_vertex_buffer(NULL) + , m_render_texture_cmd_allocator(NULL) + , m_render_texture_cmd_list(NULL) +{ +} + +UINT64 CalcByteAlignedValue(unsigned int byteSize, unsigned int byteAlignment) { + UINT byteAlignmentMinusOne = byteAlignment - 2; + return (byteSize + byteAlignmentMinusOne) & ~byteAlignmentMinusOne; } -UINT64 RenderAPI_D3D12::AlignPow2(UINT64 value) +UINT64 RenderAPI_D3D12::align_pow2(UINT64 value) { - UINT64 aligned = pow(2, (int)log2(value)); - return aligned >= value ? aligned : aligned * 2; + UINT64 aligned = static_cast(pow(2, (int)log2(value))); + return aligned >= value ? aligned : aligned * 2; } -UINT64 RenderAPI_D3D12::GetAlignedSize( int width, int height, int pixelSize, int rowPitch) +UINT64 RenderAPI_D3D12::get_aligned_size(int width, int height, int pixelSize, int rowPitch) { - UINT64 size = width * height * pixelSize; + UINT64 size = width * height * pixelSize; - size = AlignPow2(size); + size = align_pow2(size); - if (size < D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT) - { - return D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT; - } - else if (width * pixelSize < rowPitch) - { - return rowPitch * height; - } - else - { - return size; - } + if (size < D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT) + { + return D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT; + } + else if (width * pixelSize < rowPitch) + { + return rowPitch * height; + } + else + { + return size; + } } -ID3D12Resource* RenderAPI_D3D12::GetUploadResource(UINT64 size) +bool RenderAPI_D3D12::create_D3D12_default_buffer(ID3D12GraphicsCommandList* cmdLst, const void* initData, unsigned int bufferSizeInBytes, LPCWSTR uploadHeapResourceName, LPCWSTR defaultHeapResourceName, D3D12DefaultBufferMemoryObject& outMemoryObj) { - if (s_D3D12Upload) - { - D3D12_RESOURCE_DESC desc = s_D3D12Upload->GetDesc(); - if (desc.Width == size) - return s_D3D12Upload; - else - s_D3D12Upload->Release(); - } + if (!cmdLst) + return false; - // Texture upload buffer - D3D12_HEAP_PROPERTIES heapProps = {}; - heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; - heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - heapProps.CreationNodeMask = kNodeMask; - heapProps.VisibleNodeMask = kNodeMask; + if (!create_D3D12_buffer(bufferSizeInBytes, D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_GENERIC_READ, uploadHeapResourceName, &outMemoryObj.uploadResource)) + return false; - D3D12_RESOURCE_DESC heapDesc = {}; - heapDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - heapDesc.Alignment = 0; - heapDesc.Width = size; - heapDesc.Height = 1; - heapDesc.DepthOrArraySize = 1; - heapDesc.MipLevels = 1; - heapDesc.Format = DXGI_FORMAT_UNKNOWN; - heapDesc.SampleDesc.Count = 1; - heapDesc.SampleDesc.Quality = 0; - heapDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; - heapDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + if (!create_D3D12_buffer(bufferSizeInBytes, D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_FLAG_NONE, D3D12_RESOURCE_STATE_COMMON, defaultHeapResourceName, &outMemoryObj.defaultResource)) + return false; - ID3D12Device* device = s_D3D12->GetDevice(); - HRESULT hr = device->CreateCommittedResource( - &heapProps, - D3D12_HEAP_FLAG_NONE, - &heapDesc, - D3D12_RESOURCE_STATE_GENERIC_READ, - nullptr, - IID_PPV_ARGS(&s_D3D12Upload)); - if (FAILED(hr)) - { - OutputDebugStringA("Failed to CreateCommittedResource.\n"); - } + ID3D12Resource* uploadResource = outMemoryObj.uploadResource.resource; + ID3D12Resource* defaultResource = outMemoryObj.defaultResource.resource; - return s_D3D12Upload; -} + D3D12_SUBRESOURCE_DATA subResourceDataDesc; + subResourceDataDesc.pData = initData; + subResourceDataDesc.RowPitch = outMemoryObj.uploadResource.deviceMemorySize; + subResourceDataDesc.SlicePitch = subResourceDataDesc.RowPitch; + transition_barrier(cmdLst, defaultResource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); + UpdateSubresources<1>(cmdLst, defaultResource, uploadResource, 0, 0, 1, &subResourceDataDesc); + transition_barrier(cmdLst, defaultResource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON); + + return true; +} -void RenderAPI_D3D12::CreateResources() +bool RenderAPI_D3D12::create_D3D12_buffer(size_t sizeInBytes, D3D12_HEAP_TYPE heapType, D3D12_RESOURCE_FLAGS resourceFlags, D3D12_RESOURCE_STATES initialResourceState, LPCWSTR resourceName, D3D12MemoryObject* buffer) { - ID3D12Device* device = s_D3D12->GetDevice(); + ID3D12Device* device = s_d3d12->GetDevice(); + + UINT64 alignedBufferSizeInBytes = CalcByteAlignedValue(static_cast(sizeInBytes), 256); + + HRESULT hr = S_OK; + + CD3DX12_HEAP_PROPERTIES heap_props = CD3DX12_HEAP_PROPERTIES(heapType); + CD3DX12_RESOURCE_DESC resource_desc = CD3DX12_RESOURCE_DESC::Buffer(alignedBufferSizeInBytes, resourceFlags); + + ReturnOnFail( + device->CreateCommittedResource( + &heap_props, + D3D12_HEAP_FLAG_NONE, + &resource_desc, + initialResourceState, + NULL, + IID_PPV_ARGS(&buffer->resource)), + hr, + "CreateD3D12Buffer Failed\n", + false + ); + + if (heapType == D3D12_HEAP_TYPE_UPLOAD) + { + hr = buffer->resource->Map(0, NULL, &buffer->mapped); + if (FAILED(hr)) + { + OutputDebugStringA("Failed to map buffer.\n"); + buffer->resource->Release(); + buffer->resource = NULL; + return false; + } + } + else + buffer->mapped = NULL; - HRESULT hr = E_FAIL; + buffer->heapType = heapType; + buffer->resourceFlags = resourceFlags; + buffer->deviceMemorySize = alignedBufferSizeInBytes; + buffer->resourceFlags = resourceFlags; - // Command list - hr = device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&s_D3D12CmdAlloc)); - if (FAILED(hr)) OutputDebugStringA("Failed to CreateCommandAllocator.\n"); - hr = device->CreateCommandList(kNodeMask, D3D12_COMMAND_LIST_TYPE_DIRECT, s_D3D12CmdAlloc, nullptr, IID_PPV_ARGS(&s_D3D12CmdList)); - if (FAILED(hr)) OutputDebugStringA("Failed to CreateCommandList.\n"); - s_D3D12CmdList->Close(); + if (resourceName != NULL) + buffer->resource->SetName(resourceName); - // Fence - s_D3D12FenceValue = 0; - s_D3D12Event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + return true; } +void RenderAPI_D3D12::create_triangle_input_layout() +{ + m_triangle_layout[0] = D3D12_INPUT_ELEMENT_DESC( + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + ); + + m_triangle_layout[1] = D3D12_INPUT_ELEMENT_DESC( + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 } + ); +} -void RenderAPI_D3D12::ReleaseResources() +bool RenderAPI_D3D12::create_triangle_root_signature() { - SAFE_RELEASE(s_D3D12Upload); - if (s_D3D12Event) - CloseHandle(s_D3D12Event); - SAFE_RELEASE(s_D3D12CmdList); - SAFE_RELEASE(s_D3D12CmdAlloc); + HRESULT hr = S_OK; + CD3DX12_ROOT_PARAMETER slotRootParameter[1]; + + slotRootParameter[0].InitAsConstants(64, 0, 0, D3D12_SHADER_VISIBILITY_ALL); + + CD3DX12_ROOT_SIGNATURE_DESC rsDesc(1, slotRootParameter, 0, NULL, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT); + ID3DBlob* serializedRootSigBlob = NULL; + ID3DBlob* errorBlob = NULL; + + ReturnOnFail( + D3D12SerializeRootSignature(&rsDesc, D3D_ROOT_SIGNATURE_VERSION_1, &serializedRootSigBlob, &errorBlob), + hr, + "D3D12SerializeRootSignature Failed\n", + false + ); + + ID3D12Device* device = s_d3d12->GetDevice(); + ReturnOnFail( + device->CreateRootSignature(0, serializedRootSigBlob->GetBufferPointer(), serializedRootSigBlob->GetBufferSize(), __uuidof(ID3D12RootSignature), reinterpret_cast(&m_triangle_rootsig)); , + hr, + "CreateRootSignature Failed\n", + false + ); + + return true; } +ID3D12PipelineState* RenderAPI_D3D12::create_triangle_pipeline() +{ + HRESULT hr = S_OK; -void RenderAPI_D3D12::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces) + if (!create_triangle_root_signature()) + return NULL; + + create_triangle_input_layout(); + + D3D12_GRAPHICS_PIPELINE_STATE_DESC desc; + ZeroMemory(&desc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC)); + + desc.InputLayout = { m_triangle_layout, 2 }; + desc.pRootSignature = m_triangle_rootsig; + desc.VS = { + vertex_shader, + sizeof(vertex_shader) + }; + + desc.PS = { + pixel_shader, + sizeof(pixel_shader) + }; + + desc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT); + desc.RasterizerState.MultisampleEnable = true; + desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + + desc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT); + desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + desc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT); + desc.DepthStencilState.DepthEnable = true; + desc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; // Unity uses reverse z depth + desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL; + + desc.SampleMask = UINT_MAX; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.NumRenderTargets = 1; + desc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.DSVFormat = DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + + ID3D12Device* device = s_d3d12->GetDevice(); + ReturnOnFail( + device->CreateGraphicsPipelineState(&desc, __uuidof(ID3D12PipelineState), reinterpret_cast(&m_triangle_pso)), + hr, + "CreateGraphicsPipelineState Failed\n", + NULL + ); + + return m_triangle_pso; +} + +bool RenderAPI_D3D12::get_upload_resource(ID3D12Resource** outResource, UINT64 size, LPCWSTR name) { - switch (type) - { - case kUnityGfxDeviceEventInitialize: - s_D3D12 = interfaces->Get(); - CreateResources(); - break; - case kUnityGfxDeviceEventShutdown: - ReleaseResources(); - break; - } + ID3D12Resource*& resource = *outResource; + if (resource) + { + D3D12_RESOURCE_DESC desc = resource->GetDesc(); + if (desc.Width == size) + return true; + else + { + resource->Release(); + return false; + } + } + + // Texture upload buffer + D3D12_HEAP_PROPERTIES heapProps = {}; + heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heapProps.CreationNodeMask = kNodeMask; + heapProps.VisibleNodeMask = kNodeMask; + + D3D12_RESOURCE_DESC heapDesc = {}; + heapDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + heapDesc.Alignment = 0; + heapDesc.Width = size; + heapDesc.Height = 1; + heapDesc.DepthOrArraySize = 1; + heapDesc.MipLevels = 1; + heapDesc.Format = DXGI_FORMAT_UNKNOWN; + heapDesc.SampleDesc.Count = 1; + heapDesc.SampleDesc.Quality = 0; + heapDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + heapDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + HRESULT hr = S_OK; + ID3D12Device* device = s_d3d12->GetDevice(); + ReturnOnFail( + device->CreateCommittedResource( + &heapProps, + D3D12_HEAP_FLAG_NONE, + &heapDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + nullptr, + IID_PPV_ARGS(&resource)), + hr, + "CreateCommittedResource Failed\n", + false + ); + + if (name != NULL) + resource->SetName(name); + + return true; } +void RenderAPI_D3D12::ProcessDeviceEvent(UnityGfxDeviceEventType type, IUnityInterfaces* interfaces) +{ + switch (type) + { + case kUnityGfxDeviceEventInitialize: + s_d3d12 = interfaces->Get(); + + UnityD3D12PluginEventConfig config_1; + config_1.graphicsQueueAccess = kUnityD3D12GraphicsQueueAccess_DontCare; + config_1.flags = kUnityD3D12EventConfigFlag_SyncWorkerThreads | kUnityD3D12EventConfigFlag_ModifiesCommandBuffersState | kUnityD3D12EventConfigFlag_EnsurePreviousFrameSubmission; + config_1.ensureActiveRenderTextureIsBound = true; + s_d3d12->ConfigureEvent(1, &config_1); + + UnityD3D12PluginEventConfig config_2; + config_2.graphicsQueueAccess = kUnityD3D12GraphicsQueueAccess_Allow; + config_2.flags = kUnityD3D12EventConfigFlag_SyncWorkerThreads | kUnityD3D12EventConfigFlag_ModifiesCommandBuffersState | kUnityD3D12EventConfigFlag_EnsurePreviousFrameSubmission; + config_2.ensureActiveRenderTextureIsBound = false; + s_d3d12->ConfigureEvent(2, &config_2); + + initialize_and_create_resources(); + break; + case kUnityGfxDeviceEventShutdown: + release_resources(); + break; + } +} void RenderAPI_D3D12::DrawSimpleTriangles(const float worldMatrix[16], int triangleCount, const void* verticesFloat3Byte4) { - //@TODO: example not implemented yet :) + UnityGraphicsD3D12RecordingState recordingState; + if (!s_d3d12->CommandRecordingState(&recordingState)) + return; + + if (m_triangle_pso == NULL) + { + m_triangle_pso = create_triangle_pipeline(); + } + + if (m_triangle_pso != NULL) + { + ID3D12GraphicsCommandList* cmdLst = recordingState.commandList; + + garbage_collect(); + + const int kVertexSize = 12 + 4; // 12 bytes for position and 4 bytes for color + const UINT vertexBufferSizeInBytes = kVertexSize * 3 * triangleCount; + if (!create_D3D12_default_buffer(cmdLst, verticesFloat3Byte4, vertexBufferSizeInBytes, D3D12_UPLOAD_HEAP_TRIANGLE_BUFFER_NAME, D3D12_DEFAULT_HEAP_TRIANGLE_BUFFER_NAME, m_triangle_vertex_buffer)) + return; + + cmdLst->SetPipelineState(m_triangle_pso); + cmdLst->SetGraphicsRootSignature(m_triangle_rootsig); + cmdLst->SetGraphicsRoot32BitConstants(0, 64, worldMatrix, 0); + + D3D12_VERTEX_BUFFER_VIEW vbView; + vbView.BufferLocation = m_triangle_vertex_buffer.defaultResource.resource->GetGPUVirtualAddress(); + vbView.SizeInBytes = vertexBufferSizeInBytes; + vbView.StrideInBytes = kVertexSize; + + cmdLst->IASetVertexBuffers(0, 1, &vbView); + cmdLst->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + cmdLst->DrawInstanced(triangleCount * 3, 1, 0, 0); + + UINT64 nextval = s_d3d12->GetNextFrameFenceValue(); + + ID3D12Fence* fence = s_d3d12->GetFrameFence(); + UINT64 lastCompletedFenceValue = fence->GetCompletedValue(); + lastCompletedFenceValue += 3; + safe_destroy(lastCompletedFenceValue, m_triangle_vertex_buffer.uploadResource); + safe_destroy(lastCompletedFenceValue, m_triangle_vertex_buffer.defaultResource); + } } +void RenderAPI_D3D12::safe_destroy(unsigned long long frameNumber, const D3D12MemoryObject& buffer) +{ + m_DeleteQueue[frameNumber].push_back(buffer); +} -void* RenderAPI_D3D12::BeginModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int* outRowPitch) +void RenderAPI_D3D12::garbage_collect(bool force /*= false*/) { - ID3D12Fence* fence = s_D3D12->GetFrameFence(); + ID3D12Fence* fence = s_d3d12->GetFrameFence(); + UINT64 lastCompletedFenceValue = fence->GetCompletedValue(); - // Wait on the previous job (example only - simplifies resource management) - if (fence->GetCompletedValue() < s_D3D12FenceValue) - { - fence->SetEventOnCompletion(s_D3D12FenceValue, s_D3D12Event); - WaitForSingleObject(s_D3D12Event, INFINITE); - } + DeleteQueue::iterator it = m_DeleteQueue.begin(); + while (it != m_DeleteQueue.end()) + { + if (force || it->first <= lastCompletedFenceValue) + { + for (size_t i = 0; i < it->second.size(); ++i) + immediate_destroy_d3d12_buffer(it->second[i]); + m_DeleteQueue.erase(it++); + } + else + ++it; + } +} + +void RenderAPI_D3D12::immediate_destroy_d3d12_buffer(D3D12MemoryObject& buffer) +{ + if (buffer.resource == NULL) + return; - // Begin a command list - s_D3D12CmdAlloc->Reset(); - s_D3D12CmdList->Reset(s_D3D12CmdAlloc, nullptr); + if (buffer.mapped) + { + buffer.resource->Unmap(0, NULL); + buffer.mapped = 0; + } - // Fill data - // Clamp to minimum rowPitch of RGBA32 - *outRowPitch = max(AlignPow2(textureWidth * 4), 256); - const UINT64 kDataSize = GetAlignedSize(textureWidth, textureHeight, 4, *outRowPitch); - ID3D12Resource* upload = GetUploadResource(kDataSize); - void* mapped = NULL; - upload->Map(0, NULL, &mapped); - return mapped; + SAFE_RELEASE(buffer.resource); } +void RenderAPI_D3D12::initialize_and_create_resources() +{ + if (m_are_resources_initialized) + return; -void RenderAPI_D3D12::EndModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int rowPitch, void* dataPtr) + ID3D12Device* device = s_d3d12->GetDevice(); + assert(device != nullptr); + + UnityGraphicsD3D12PhysicalVideoMemoryControlValues control_values; + control_values.reservation = 64000000; + control_values.systemMemoryThreshold = 64000000; + control_values.residencyHysteresisThreshold = 128000000; + control_values.nonEvictableRelativeThreshold = 0.25; + s_d3d12->SetPhysicalVideoMemoryControlValues(&control_values); + + constexpr Vertex vertices[] { + // position color + // <---------------> <--------------------> + {{ 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, + {{ 1.0f, -1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, + {{ -1.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } + }; + + D3D12_INPUT_ELEMENT_DESC position = {}; + position.SemanticName = "POSITION"; + position.SemanticIndex = 0; + position.Format = DXGI_FORMAT_R32G32B32_FLOAT; + position.AlignedByteOffset = 0; + position.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + position.InstanceDataStepRate = 0; + + D3D12_INPUT_ELEMENT_DESC color = {}; + color.SemanticName = "COLOR"; + color.SemanticIndex = 0; + color.Format = DXGI_FORMAT_R32G32B32A32_FLOAT; + color.AlignedByteOffset = 12; + color.InputSlotClass = D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA; + color.InstanceDataStepRate = 0; + + D3D12_INPUT_ELEMENT_DESC input_element_desc[] = {position, color}; + + D3D12_RESOURCE_DESC vertex_buffer_desc = {}; + vertex_buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + vertex_buffer_desc.Alignment = 0; + vertex_buffer_desc.Width = sizeof(vertices); + vertex_buffer_desc.Height = 1; + vertex_buffer_desc.DepthOrArraySize = 1; + vertex_buffer_desc.MipLevels = 1; + vertex_buffer_desc.Format = DXGI_FORMAT_UNKNOWN; + vertex_buffer_desc.SampleDesc.Count = 1; + vertex_buffer_desc.SampleDesc.Quality = 0; + vertex_buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + vertex_buffer_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + D3D12_HEAP_PROPERTIES vertex_buffer_heap_props = {}; + vertex_buffer_heap_props.Type = D3D12_HEAP_TYPE_UPLOAD; + vertex_buffer_heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + vertex_buffer_heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + vertex_buffer_heap_props.CreationNodeMask = 1; + vertex_buffer_heap_props.VisibleNodeMask = 1; + + handle_hr(device->CreateCommittedResource(&vertex_buffer_heap_props, D3D12_HEAP_FLAG_NONE, &vertex_buffer_desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&m_render_texture_vertex_buffer)), + "Failed to create vertex buffer for render texture\n"); + + char* data; + D3D12_RANGE read_range{ 0, 0 }; + handle_hr(m_render_texture_vertex_buffer->Map(0, &read_range, reinterpret_cast(&data))); + memcpy(data, vertices, sizeof(vertices)); + m_render_texture_vertex_buffer->Unmap(0, nullptr); + + m_texture_vertex_buffer_view = {}; + m_texture_vertex_buffer_view.BufferLocation = m_render_texture_vertex_buffer->GetGPUVirtualAddress(); + m_texture_vertex_buffer_view.SizeInBytes = sizeof(vertices); + m_texture_vertex_buffer_view.StrideInBytes = sizeof(Vertex); + + // 1st descriptor is for m_render_texture and 2nd one is for m_plugin_texture + D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc = {}; + rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtv_heap_desc.NumDescriptors = 2; + rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + rtv_heap_desc.NodeMask = 0; + + handle_hr(device->CreateDescriptorHeap(&rtv_heap_desc, IID_PPV_ARGS(&m_texture_rtv_desc_heap)), + "Failed to create descriptor heap for render texture RTVs\n"); + + m_texture_rtv_desc_size = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + // When Unity does create it's own RenderBuffer and passes it to the plugin + // using setRenderTexture() we don't have to create one here. + if (!m_is_render_texture_created_by_unity) + m_render_texture = create_render_texture(); + + m_plugin_texture = create_render_texture(); + + create_render_texture_rtv(m_texture_rtv_desc_heap, m_render_texture, 0); + create_render_texture_rtv(m_texture_rtv_desc_heap, m_plugin_texture, 1); + + m_render_texture.load()->SetName(L"plugin render texture\n"); + + // we store the world matrix in the root signature + D3D12_ROOT_CONSTANTS root_constants = {}; + root_constants.ShaderRegister = 0; + root_constants.RegisterSpace = 0; + root_constants.Num32BitValues = 64; // maximum size for root sig + + D3D12_ROOT_PARAMETER root_param = {}; + root_param.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + root_param.Constants = root_constants; + root_param.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + + D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {}; + root_signature_desc.NumParameters = 1; + root_signature_desc.pParameters = &root_param; + root_signature_desc.NumStaticSamplers = 0; + root_signature_desc.pStaticSamplers = nullptr; + root_signature_desc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + handle_hr(D3D12SerializeRootSignature(&root_signature_desc, D3D_ROOT_SIGNATURE_VERSION_1, &m_render_texture_root_blob, nullptr), + "Failed to serialize root signature for render texture\n"); + handle_hr(device->CreateRootSignature(0, m_render_texture_root_blob->GetBufferPointer(), m_render_texture_root_blob->GetBufferSize(), IID_PPV_ARGS(&m_texture_root_sig)), + "Failed to create root signature for render texture\n"); + + D3D12_RASTERIZER_DESC rasterizer_desc = {}; + rasterizer_desc.FillMode = D3D12_FILL_MODE_SOLID; + rasterizer_desc.CullMode = D3D12_CULL_MODE_NONE; + rasterizer_desc.FrontCounterClockwise = FALSE; + rasterizer_desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + rasterizer_desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + rasterizer_desc.SlopeScaledDepthBias = 0; + rasterizer_desc.MultisampleEnable = FALSE; + rasterizer_desc.MultisampleEnable = FALSE; + rasterizer_desc.AntialiasedLineEnable = FALSE; + rasterizer_desc.ForcedSampleCount = 0; + rasterizer_desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + + D3D12_RENDER_TARGET_BLEND_DESC render_target_blend_desc = {}; + render_target_blend_desc.BlendEnable = FALSE; + render_target_blend_desc.LogicOpEnable = FALSE; + render_target_blend_desc.SrcBlend = D3D12_BLEND_ONE; + render_target_blend_desc.DestBlend = D3D12_BLEND_ZERO; + render_target_blend_desc.BlendOp = D3D12_BLEND_OP_ADD; + render_target_blend_desc.SrcBlendAlpha = D3D12_BLEND_ONE; + render_target_blend_desc.DestBlendAlpha = D3D12_BLEND_ZERO; + render_target_blend_desc.BlendOpAlpha = D3D12_BLEND_OP_ADD; + render_target_blend_desc.LogicOp = D3D12_LOGIC_OP_NOOP; + render_target_blend_desc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + D3D12_BLEND_DESC blend_desc = {}; + blend_desc.AlphaToCoverageEnable = FALSE; + blend_desc.IndependentBlendEnable = FALSE; + blend_desc.RenderTarget[0] = render_target_blend_desc; + + D3D12_DEPTH_STENCIL_DESC depth_stencil_desc = {}; + depth_stencil_desc.DepthEnable = FALSE; + depth_stencil_desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; + depth_stencil_desc.DepthFunc = D3D12_COMPARISON_FUNC_NEVER; + depth_stencil_desc.StencilEnable = FALSE; + + D3D12_SHADER_BYTECODE vertex_bytecode = {}; + vertex_bytecode.pShaderBytecode = (void*)(vertex_shader); + vertex_bytecode.BytecodeLength = sizeof(vertex_shader); + + D3D12_SHADER_BYTECODE pixel_bytecode = {}; + pixel_bytecode.pShaderBytecode = (void*)(pixel_shader); + pixel_bytecode.BytecodeLength = sizeof(pixel_shader); + + D3D12_INPUT_LAYOUT_DESC input_layout_desc = {}; + input_layout_desc.pInputElementDescs = input_element_desc; + input_layout_desc.NumElements = _countof(input_element_desc); + + DXGI_SAMPLE_DESC dxgi_sample_desc = {}; + dxgi_sample_desc.Count = 1; + dxgi_sample_desc.Quality = 0; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc = {}; + pso_desc.pRootSignature = m_texture_root_sig; + pso_desc.VS = vertex_bytecode; + pso_desc.PS = pixel_bytecode; + pso_desc.DS = { nullptr, 0 }; + pso_desc.HS = { nullptr, 0 }; + pso_desc.GS = { nullptr, 0 }; + pso_desc.StreamOutput = {}; + pso_desc.BlendState = blend_desc; + pso_desc.SampleMask = 1; + pso_desc.RasterizerState = rasterizer_desc; + pso_desc.DepthStencilState = depth_stencil_desc; + pso_desc.InputLayout = input_layout_desc; + pso_desc.IBStripCutValue = {}; + pso_desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + pso_desc.NumRenderTargets = 1; + pso_desc.RTVFormats[0] = {DXGI_FORMAT_R8G8B8A8_UNORM}; + pso_desc.DSVFormat = {}; + pso_desc.SampleDesc = dxgi_sample_desc; + pso_desc.NodeMask = 0; + pso_desc.CachedPSO = { nullptr, 0 }; + pso_desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + handle_hr(device->CreateGraphicsPipelineState(&pso_desc, IID_PPV_ARGS(&m_texture_pso)), + "Failed to create PSO for render texture\n"); + handle_hr(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_render_texture_cmd_allocator)), + "Failed to create cmd allocator for render texture\n"); + handle_hr(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_render_texture_cmd_allocator, nullptr, IID_PPV_ARGS(&m_render_texture_cmd_list)), + "Failed to create cmd list for render texture\n"); + + handle_hr(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_plugin_texture_cmd_allocator)), + "Failed to create cmd allocator for plugin texture\n"); + + handle_hr(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_plugin_texture_cmd_allocator, nullptr, IID_PPV_ARGS(&m_plugin_texture_cmd_list)), + "Failed to create cmd list for render texture2\n"); + + handle_hr(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_texture_copy_cmd_allocator)), + "Failed to create cmd allocator for texture copy\n"); + + handle_hr(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_vertex_copy_cmd_allocator)), + "Failed to create cmd allocator for vertex copy\n"); + + handle_hr(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_texture_copy_cmd_allocator, nullptr, IID_PPV_ARGS(&m_texture_copy_cmd_list)), + "Failed to create texture copy cmd list\n"); + + handle_hr(device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_vertex_copy_cmd_allocator, nullptr, IID_PPV_ARGS(&m_vertex_copy_cmd_list)), + "Failed to create vertex copy cmd list\n"); + + handle_hr(device->CreateFence(m_plugin_texture_fence_value, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_plugin_texture_fence)), + "Failed to create fence for plugin texture"); + + m_texture_copy_cmd_allocator->SetName(L"texture copy cmd allocator"); + m_vertex_copy_cmd_allocator->SetName(L"vertex copy cmd allocator"); + m_render_texture_cmd_allocator->SetName(L"render texture cmd allocator"); + + m_vertex_copy_cmd_list->SetName(L"vertex copy cmd list"); + m_texture_copy_cmd_list->SetName(L"texture copy cmd list"); + m_render_texture_cmd_list->SetName(L"render texture cmd list"); + + handle_hr(m_vertex_copy_cmd_list->Close(), "Failed to close cmd list for vertex copy\n"); + handle_hr(m_texture_copy_cmd_list->Close(), "Failed to close cmd list for texture copy\n"); + handle_hr(m_render_texture_cmd_list->Close(), "Failed to close cmd list for render texture\n"); + handle_hr(m_plugin_texture_cmd_list->Close(), "Failed to close cmd list for plugin texture\n"); + + m_fence_event = CreateEvent(NULL, false, false, nullptr); + m_plugin_texture_fence_event = CreateEvent(NULL, false, false, nullptr); + + D3D12_DESCRIPTOR_HEAP_DESC rtvDesc = {}; + rtvDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + rtvDesc.NumDescriptors = 1; + rtvDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + rtvDesc.NodeMask = 0; + + handle_hr(device->CreateDescriptorHeap(&rtvDesc, IID_PPV_ARGS(&m_triangle_rtv_desc_heap)), + "CreateDescriptorHeap Failed\n"); + + D3D12_DESCRIPTOR_HEAP_DESC dsvDesc = {}; + dsvDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + dsvDesc.NumDescriptors = 1; + dsvDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + dsvDesc.NodeMask = 0; + + handle_hr(device->CreateDescriptorHeap(&dsvDesc, IID_PPV_ARGS(&m_triangle_dsv_desc_heap)), + "CreateDescriptorHeap Failed\n"); + + m_are_resources_initialized = true; +} + +void RenderAPI_D3D12::release_resources() +{ + SAFE_RELEASE(m_render_texture_cmd_list); + SAFE_RELEASE(m_render_texture_cmd_allocator); + SAFE_RELEASE(m_plugin_texture_cmd_list); + SAFE_RELEASE(m_plugin_texture_cmd_allocator); + SAFE_RELEASE(m_texture_pso); + SAFE_RELEASE(m_texture_root_sig); + SAFE_RELEASE(m_render_texture_root_blob); + SAFE_RELEASE(m_texture_rtv_desc_heap); + if (!m_is_render_texture_created_by_unity) + { + ID3D12Resource* render_texture = m_render_texture.load(); + if (render_texture) + { + render_texture->Release(); + m_render_texture = nullptr; + } + } + SAFE_RELEASE(m_render_texture_vertex_buffer); + SAFE_RELEASE(m_triangle_pso); + SAFE_RELEASE(m_triangle_rootsig); + SAFE_RELEASE(m_triangle_rtv_desc_heap); + SAFE_RELEASE(m_triangle_dsv_desc_heap); + SAFE_RELEASE(s_upload_texture); + SAFE_RELEASE(s_upload_buffer); + SAFE_RELEASE(m_vertex_copy_cmd_list); + SAFE_RELEASE(m_texture_copy_cmd_list); + SAFE_RELEASE(m_vertex_copy_cmd_allocator); + SAFE_RELEASE(m_texture_copy_cmd_allocator); + + if (ID3D12Resource* plugin_texture = m_plugin_texture.load()) + { + plugin_texture->Release(); + m_plugin_texture = nullptr; + } + + CloseHandle(m_fence_event); + CloseHandle(m_plugin_texture_fence_event); + + garbage_collect(true); + m_mapped_triangle_vertex_buffers.clear(); +} + +void RenderAPI_D3D12::record_draw_cmd_list(ID3D12CommandAllocator* cmd_alloc, ID3D12GraphicsCommandList* cmd, ID3D12RootSignature* rootsig, D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle, D3D12_VERTEX_BUFFER_VIEW* vbview, const float* world_matrix, D3D12_VIEWPORT* viewport, ID3D12PipelineState* pso, ID3D12Resource* target, D3D12_RESOURCE_STATES target_state) +{ + constexpr FLOAT clear_color[4] = { 0.5f, 0.5f, 0.5f, 1.f }; + + handle_hr(cmd_alloc->Reset(), "Failed to reset cmd allocator\n"); + handle_hr(cmd->Reset(cmd_alloc, pso), "Failed to reset cmd list\n"); + + cmd->SetGraphicsRootSignature(rootsig); + cmd->SetGraphicsRoot32BitConstants(0, 64, world_matrix, 0); + + if (target_state != D3D12_RESOURCE_STATE_RENDER_TARGET) + { + transition_barrier(cmd, target, target_state, D3D12_RESOURCE_STATE_RENDER_TARGET); + } + + cmd->OMSetRenderTargets(1, &rtv_handle, FALSE, nullptr); + cmd->ClearRenderTargetView(rtv_handle, clear_color, 0, nullptr); + + D3D12_RECT scissor; + scissor.left = 0; + scissor.top = 0; + scissor.right = static_cast(viewport->Width); + scissor.bottom = static_cast(viewport->Height); + + cmd->RSSetViewports(1, viewport); + cmd->RSSetScissorRects(1, &scissor); + cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + cmd->IASetVertexBuffers(0, 1, vbview); + + const UINT vertices = vbview->SizeInBytes / vbview->StrideInBytes; + + cmd->DrawInstanced(vertices, 1, 0, 0); + + if (target_state != D3D12_RESOURCE_STATE_RENDER_TARGET) + { + transition_barrier(cmd, target, D3D12_RESOURCE_STATE_RENDER_TARGET, target_state); + } + + handle_hr(cmd->Close(), "Failed to close draw cmd list\n"); +} + +UINT64 RenderAPI_D3D12::submit_cmd_to_unity_worker(ID3D12GraphicsCommandList* cmd, UnityGraphicsD3D12ResourceState* resource_states, int state_count) +{ + return s_d3d12->ExecuteCommandList(cmd, state_count, resource_states); +} + +ID3D12Resource* RenderAPI_D3D12::create_render_texture() { - ID3D12Device* device = s_D3D12->GetDevice(); + ID3D12Device* device = s_d3d12->GetDevice(); + + DXGI_SAMPLE_DESC dxgi_sample_desc = {}; + dxgi_sample_desc.Count = 1; + dxgi_sample_desc.Quality = 0; - const UINT64 kDataSize = GetAlignedSize(textureWidth, textureHeight, 4, rowPitch); - ID3D12Resource* upload = GetUploadResource(kDataSize); - upload->Unmap(0, NULL); + D3D12_RESOURCE_DESC render_texture_desc = {}; + render_texture_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + render_texture_desc.Width = m_texture_width; + render_texture_desc.Height = m_texture_height; + render_texture_desc.DepthOrArraySize = 1; + render_texture_desc.MipLevels = 1; + render_texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + render_texture_desc.SampleDesc = dxgi_sample_desc; + render_texture_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + render_texture_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - ID3D12Resource* resource = (ID3D12Resource*)textureHandle; - D3D12_RESOURCE_DESC desc = resource->GetDesc(); - assert(desc.Width == textureWidth); - assert(desc.Height == textureHeight); + D3D12_HEAP_PROPERTIES render_texture_heap_props = {}; + render_texture_heap_props.Type = D3D12_HEAP_TYPE_DEFAULT; + render_texture_heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + render_texture_heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + render_texture_heap_props.CreationNodeMask = 1; + render_texture_heap_props.VisibleNodeMask = 1; - D3D12_TEXTURE_COPY_LOCATION srcLoc = {}; - srcLoc.pResource = upload; - srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; - device->GetCopyableFootprints(&desc, 0, 1, 0, &srcLoc.PlacedFootprint, nullptr, nullptr, nullptr); + ID3D12Resource* pRendertex; + handle_hr(device->CreateCommittedResource(&render_texture_heap_props, D3D12_HEAP_FLAG_NONE, &render_texture_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, IID_PPV_ARGS(&pRendertex)), + "Failed to create a render texture\n"); - D3D12_TEXTURE_COPY_LOCATION dstLoc = {}; - dstLoc.pResource = resource; - dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; - dstLoc.SubresourceIndex = 0; + return pRendertex; +} + +void RenderAPI_D3D12::create_render_texture_rtv(ID3D12DescriptorHeap* heap, ID3D12Resource* target, UINT offset) +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle{ heap->GetCPUDescriptorHandleForHeapStart() }; + rtv_handle.Offset(offset, m_texture_rtv_desc_size); - // We inform Unity that we expect this resource to be in D3D12_RESOURCE_STATE_COPY_DEST state, - // and because we do not barrier it ourselves, we tell Unity that no changes are done on our command list. - UnityGraphicsD3D12ResourceState resourceState = {}; - resourceState.resource = resource; - resourceState.expected = D3D12_RESOURCE_STATE_COPY_DEST; - resourceState.current = D3D12_RESOURCE_STATE_COPY_DEST; + D3D12_TEX2D_RTV rtv; + rtv.MipSlice = 0; + rtv.PlaneSlice = 0; - // Queue data upload - s_D3D12CmdList->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); + D3D12_RENDER_TARGET_VIEW_DESC desc; + desc.Format = typeless_fmt_to_typed(target->GetDesc().Format); + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + desc.Texture2D = rtv; - // Execute the command list - s_D3D12CmdList->Close(); - s_D3D12FenceValue = s_D3D12->ExecuteCommandList(s_D3D12CmdList, 1, &resourceState); + s_d3d12->GetDevice()->CreateRenderTargetView(target, &desc, rtv_handle); } +void RenderAPI_D3D12::transition_barrier(ID3D12GraphicsCommandList* cmd, ID3D12Resource* resource, D3D12_RESOURCE_STATES before, D3D12_RESOURCE_STATES after) +{ + D3D12_RESOURCE_TRANSITION_BARRIER transition = {}; + transition.pResource = resource; + transition.Subresource = 0; + transition.StateBefore = before; + transition.StateAfter = after; -void* RenderAPI_D3D12::BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize) + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition = transition; + + cmd->ResourceBarrier(1, &barrier); +} + +void RenderAPI_D3D12::wait_for_unity_frame_fence(UINT64 fence_value) { - //@TODO - return NULL; + ID3D12Fence* unity_fence = s_d3d12->GetFrameFence(); + UINT64 current_fence_value = unity_fence->GetCompletedValue(); + + if (current_fence_value < fence_value) + { + handle_hr(unity_fence->SetEventOnCompletion(fence_value, m_fence_event), "Failed to set fence event on completion\n"); + WaitForSingleObject(m_fence_event, INFINITE); + } +} + +void RenderAPI_D3D12::wait_on_fence(UINT64 fence_value, ID3D12Fence* fence, HANDLE fence_event) +{ + UINT64 current_fence_value = fence->GetCompletedValue(); + + if (current_fence_value < fence_value) + { + handle_hr(fence->SetEventOnCompletion(fence_value, fence_event)); + WaitForSingleObject(fence_event, INFINITE); + } +} + +DXGI_FORMAT RenderAPI_D3D12::typeless_fmt_to_typed(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + return DXGI_FORMAT_R32G32B32A32_UINT; + + case DXGI_FORMAT_R32G32B32_TYPELESS: + return DXGI_FORMAT_R32G32B32_UINT; + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + return DXGI_FORMAT_R16G16B16A16_UNORM; + + case DXGI_FORMAT_R32G32_TYPELESS: + return DXGI_FORMAT_R32G32_UINT; + + case DXGI_FORMAT_R32G8X24_TYPELESS: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + return DXGI_FORMAT_R8G8B8A8_UNORM; + + case DXGI_FORMAT_R16G16_TYPELESS: + return DXGI_FORMAT_R16G16_UNORM; + + case DXGI_FORMAT_R32_TYPELESS: + return DXGI_FORMAT_R32_UINT; + + case DXGI_FORMAT_R24G8_TYPELESS: + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + + case DXGI_FORMAT_R8G8_TYPELESS: + return DXGI_FORMAT_R8G8_UNORM; + + case DXGI_FORMAT_R16_TYPELESS: + return DXGI_FORMAT_R16_UNORM; + + case DXGI_FORMAT_R8_TYPELESS: + return DXGI_FORMAT_R8_UNORM; + + case DXGI_FORMAT_BC1_TYPELESS: + return DXGI_FORMAT_BC1_UNORM; + + case DXGI_FORMAT_BC2_TYPELESS: + return DXGI_FORMAT_BC2_UNORM; + + case DXGI_FORMAT_BC3_TYPELESS: + return DXGI_FORMAT_BC3_UNORM; + + case DXGI_FORMAT_BC4_TYPELESS: + return DXGI_FORMAT_BC4_UNORM; + + case DXGI_FORMAT_BC5_TYPELESS: + return DXGI_FORMAT_BC5_UNORM; + + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + case DXGI_FORMAT_BC6H_TYPELESS: + return DXGI_FORMAT_BC6H_UF16; + + case DXGI_FORMAT_BC7_TYPELESS: + return DXGI_FORMAT_BC7_UNORM; + + default: + return format; + } +} + +void* RenderAPI_D3D12::BeginModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int* outRowPitch) +{ + wait_for_unity_frame_fence(m_texture_copy_fence); + + // Fill data + // Clamp to minimum rowPitch of RGBA32 + *outRowPitch = static_cast(max(align_pow2(textureWidth * 4), 256)); + const UINT64 kDataSize = get_aligned_size(textureWidth, textureHeight, 4, *outRowPitch); + if (!get_upload_resource(&s_upload_texture, kDataSize, D3D12_UPLOAD_HEAP_TEXTURE_BUFFER_NAME)) + return NULL; + + void* mapped = NULL; + s_upload_texture->Map(0, NULL, &mapped); + return mapped; +} + +void RenderAPI_D3D12::EndModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int rowPitch, void* dataPtr) +{ + ID3D12Device* device = s_d3d12->GetDevice(); + + const UINT64 kDataSize = get_aligned_size(textureWidth, textureHeight, 4, rowPitch); + if (!get_upload_resource(&s_upload_texture, kDataSize, D3D12_UPLOAD_HEAP_TEXTURE_BUFFER_NAME)) + return; + + s_upload_texture->Unmap(0, 0); + + ID3D12Resource* resource = (ID3D12Resource*)textureHandle; + D3D12_RESOURCE_DESC desc = resource->GetDesc(); + assert(desc.Width == textureWidth); + assert(desc.Height == textureHeight); + + D3D12_TEXTURE_COPY_LOCATION srcLoc = {}; + srcLoc.pResource = s_upload_texture; + srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + device->GetCopyableFootprints(&desc, 0, 1, 0, &srcLoc.PlacedFootprint, nullptr, nullptr, nullptr); + + D3D12_TEXTURE_COPY_LOCATION dstLoc = {}; + dstLoc.pResource = resource; + dstLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLoc.SubresourceIndex = 0; + + m_texture_copy_cmd_allocator->Reset(); + m_texture_copy_cmd_list->Reset(m_texture_copy_cmd_allocator, nullptr); + transition_barrier(m_texture_copy_cmd_list, resource, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); + m_texture_copy_cmd_list->CopyTextureRegion(&dstLoc, 0, 0, 0, &srcLoc, nullptr); + transition_barrier(m_texture_copy_cmd_list, resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON); + m_texture_copy_cmd_list->Close(); + + UnityGraphicsD3D12ResourceState resource_states = {}; + resource_states.resource = resource; + resource_states.expected = D3D12_RESOURCE_STATE_COMMON; + resource_states.current = D3D12_RESOURCE_STATE_COMMON; + + m_texture_copy_fence = submit_cmd_to_unity_worker(m_texture_copy_cmd_list, &resource_states, 1); } +void* RenderAPI_D3D12::BeginModifyVertexBuffer(void* bufferHandle, size_t* outBufferSize) +{ + wait_for_unity_frame_fence(m_vertex_copy_fence); + + if (bufferHandle == NULL) + return NULL; + + ID3D12Resource* unity_vertex_buffer = reinterpret_cast(bufferHandle); + D3D12_RESOURCE_DESC desc = unity_vertex_buffer->GetDesc(); + *outBufferSize = static_cast(desc.Width); + + if (!get_upload_resource(&s_upload_buffer, desc.Width, D3D12_UPLOAD_HEAP_VERTEX_BUFFER_NAME)) + return NULL; + + MappedVertexBuffers::iterator it = m_mapped_triangle_vertex_buffers.find(bufferHandle); + if (it == m_mapped_triangle_vertex_buffers.end()) + m_mapped_triangle_vertex_buffers.insert(std::make_pair(bufferHandle, reinterpret_cast(new int()))); + + HRESULT hr = s_upload_buffer->Map(0, 0, &m_mapped_triangle_vertex_buffers[bufferHandle]); + return m_mapped_triangle_vertex_buffers[bufferHandle]; +} void RenderAPI_D3D12::EndModifyVertexBuffer(void* bufferHandle) { - //@TODO + m_vertex_copy_cmd_allocator->Reset(); + m_vertex_copy_cmd_list->Reset(m_vertex_copy_cmd_allocator, nullptr); + + if (bufferHandle == NULL) + return; + + UnityGraphicsD3D12RecordingState recordingState; + if (!s_d3d12->CommandRecordingState(&recordingState)) + return; + + ID3D12Resource* unity_vertex_buffer = reinterpret_cast(bufferHandle); + D3D12_RESOURCE_DESC desc = unity_vertex_buffer->GetDesc(); + if (!get_upload_resource(&s_upload_buffer, desc.Width, D3D12_UPLOAD_HEAP_VERTEX_BUFFER_NAME)) + return; + + assert(desc.Height == 1); + + s_upload_buffer->Unmap(0, 0); + + D3D12_HEAP_PROPERTIES heap_props; + handle_hr(unity_vertex_buffer->GetHeapProperties(&heap_props, nullptr), "Failed to get heap properties for unitys vertex buffer"); + + // On DX12 Mesh.MarkDynamic() doesn't guarantee the underlying resource to be CPU mappable. In the case when it's not we need to + // place correct transition barriers before and after the copy command. + + if (heap_props.Type == D3D12_HEAP_TYPE_DEFAULT) + transition_barrier(m_vertex_copy_cmd_list, unity_vertex_buffer, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST); + + m_vertex_copy_cmd_list->CopyBufferRegion(unity_vertex_buffer, 0, s_upload_buffer, 0, desc.Width); + + if (heap_props.Type == D3D12_HEAP_TYPE_DEFAULT) + transition_barrier(m_vertex_copy_cmd_list, unity_vertex_buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COMMON); + + handle_hr(m_vertex_copy_cmd_list->Close(), "Failed to close vertex copy cmd list"); + + UnityGraphicsD3D12ResourceState resource_states = {}; + if (heap_props.Type == D3D12_HEAP_TYPE_DEFAULT) + { + resource_states.resource = unity_vertex_buffer; + resource_states.expected = D3D12_RESOURCE_STATE_COMMON; + resource_states.current = D3D12_RESOURCE_STATE_COMMON; + } + + m_vertex_copy_fence = submit_cmd_to_unity_worker(m_vertex_copy_cmd_list, &resource_states, 1); +} + +void RenderAPI_D3D12::drawToPluginTexture() +{ + if (!m_plugin_texture) + return; + + wait_on_fence(m_plugin_texture_fence_value, m_plugin_texture_fence, m_plugin_texture_fence_event); + + // Draw the triangle upside down + constexpr float world_matrix[16] = { 1, 0, 0, 0, + 0,-1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + + D3D12_VIEWPORT viewport = {}; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast(m_texture_width); + viewport.Height = static_cast(m_texture_height); + viewport.MinDepth = D3D12_MIN_DEPTH; + viewport.MaxDepth = D3D12_MAX_DEPTH; + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle { m_texture_rtv_desc_heap->GetCPUDescriptorHandleForHeapStart() }; + rtv_handle.Offset(1, m_texture_rtv_desc_size); + + // We can reuse some of the resources for both plugin_texture and render_texture + record_draw_cmd_list(m_plugin_texture_cmd_allocator, + m_plugin_texture_cmd_list, + m_texture_root_sig, + rtv_handle, + &m_texture_vertex_buffer_view, + world_matrix, &viewport, + m_texture_pso, + m_plugin_texture, + D3D12_RESOURCE_STATE_RENDER_TARGET); + + ID3D12CommandQueue* unity_command_queue = s_d3d12->GetCommandQueue(); + unity_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)&m_plugin_texture_cmd_list); + unity_command_queue->Signal(m_plugin_texture_fence, ++m_plugin_texture_fence_value); +} + +void RenderAPI_D3D12::drawToRenderTexture() +{ + wait_for_unity_frame_fence(m_render_texture_draw_fence); + + if (!m_render_texture) + return; + + // Draw the triangle upright + constexpr float world_matrix[16] = { 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + + D3D12_VIEWPORT viewport = {}; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = static_cast(m_texture_width); + viewport.Height = static_cast(m_texture_height); + viewport.MinDepth = D3D12_MIN_DEPTH; + viewport.MaxDepth = D3D12_MAX_DEPTH; + + CD3DX12_CPU_DESCRIPTOR_HANDLE rtv_handle { m_texture_rtv_desc_heap->GetCPUDescriptorHandleForHeapStart() }; + rtv_handle.Offset(0, m_texture_rtv_desc_size); + + D3D12_RESOURCE_STATES target_state; + if (m_is_render_texture_created_by_unity) + { + target_state = D3D12_RESOURCE_STATE_COMMON; + } + else + { + target_state = D3D12_RESOURCE_STATE_RENDER_TARGET; + } + + record_draw_cmd_list(m_render_texture_cmd_allocator, + m_render_texture_cmd_list, + m_texture_root_sig, + rtv_handle, + &m_texture_vertex_buffer_view, + world_matrix, &viewport, + m_texture_pso, + m_render_texture, + target_state); + + UnityGraphicsD3D12ResourceState resource_states; + resource_states.resource = m_render_texture; + resource_states.expected = D3D12_RESOURCE_STATE_COMMON; + resource_states.current = D3D12_RESOURCE_STATE_COMMON; + + m_render_texture_draw_fence = submit_cmd_to_unity_worker(m_render_texture_cmd_list, &resource_states, 1); +} + +void* RenderAPI_D3D12::getRenderTexture() +{ + return reinterpret_cast(m_render_texture.load()); +} + +void RenderAPI_D3D12::setRenderTextureResource(UnityRenderBuffer rb) +{ + // Release existing resource if there is already one that wasn't created by Unity C# script + if (!m_is_render_texture_created_by_unity && m_render_texture) + { + m_render_texture.load()->Release(); + m_render_texture = nullptr; + } + + // rb == nullptr is used to signal that the previously used UnityRenderBuffer + // is not available anymore (i.e when it gets destroyed) + if (!rb) + { + m_render_texture = nullptr; + m_is_render_texture_created_by_unity = false; + return; + } + + // TextureFromRenderBuffer might not be immediately available when this function is called. + ID3D12Resource* rb_resource = nullptr; + while (!rb_resource) + { + rb_resource = s_d3d12->TextureFromRenderBuffer(rb); + } + + D3D12_RESOURCE_DESC desc = rb_resource->GetDesc(); + m_texture_width = desc.Width; + m_texture_height = desc.Height; + assert(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D); + assert(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET); + + m_render_texture = rb_resource; + + // we need to update the rtv if we won't be calling initialize_render_texture_resources() after + // (when it's already initialized) + if (m_are_resources_initialized) + create_render_texture_rtv(m_texture_rtv_desc_heap, m_render_texture, 0); + + m_is_render_texture_created_by_unity = true; } +bool RenderAPI_D3D12::isSwapChainAvailable() +{ + return s_d3d12->GetSwapChain(); +} + +unsigned int RenderAPI_D3D12::getPresentFlags() +{ + return s_d3d12->GetPresentFlags(); +}; + +unsigned int RenderAPI_D3D12::getSyncInterval() +{ + return s_d3d12->GetSyncInterval(); +} + +unsigned int RenderAPI_D3D12::getBackbufferWidth() +{ + IDXGISwapChain* swap_chain = s_d3d12->GetSwapChain(); + if (!swap_chain) + return 0; + + DXGI_SWAP_CHAIN_DESC desc; + handle_hr(swap_chain->GetDesc(&desc), "Failed to get DXGI swap chain desc\n"); + + return desc.BufferDesc.Width; +} + +unsigned int RenderAPI_D3D12::getBackbufferHeight() +{ + IDXGISwapChain* swap_chain = s_d3d12->GetSwapChain(); + if (!swap_chain) + return 0; + + DXGI_SWAP_CHAIN_DESC desc; + handle_hr(swap_chain->GetDesc(&desc), "Failed to get DXGI swap chain desc\n"); + + return desc.BufferDesc.Height; +} + +#undef ReturnOnFail + #endif // #if SUPPORT_D3D12 diff --git a/PluginSource/source/RenderAPI_Metal.mm b/PluginSource/source/RenderAPI_Metal.mm index f7abf0f7..dd1cc9c5 100644 --- a/PluginSource/source/RenderAPI_Metal.mm +++ b/PluginSource/source/RenderAPI_Metal.mm @@ -142,7 +142,6 @@ pipeDesc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8; pipeDesc.stencilAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8; - pipeDesc.sampleCount = 1; pipeDesc.colorAttachments[0].blendingEnabled = NO; pipeDesc.vertexFunction = vertexFunction; @@ -199,8 +198,10 @@ ::memcpy(m_ConstantBuffer.contents, worldMatrix, cbSize); #if UNITY_OSX - [m_VertexBuffer didModifyRange:NSMakeRange(0, vbSize)]; - [m_ConstantBuffer didModifyRange:NSMakeRange(0, cbSize)]; + if (m_VertexBuffer.storageMode == MTLStorageModeManaged) + [m_VertexBuffer didModifyRange:NSMakeRange(0, vbSize)]; + if (m_ConstantBuffer.storageMode == MTLStorageModeManaged) + [m_ConstantBuffer didModifyRange:NSMakeRange(0, cbSize)]; #endif id cmd = (id)m_MetalGraphics->CurrentCommandEncoder(); @@ -250,7 +251,8 @@ { # if UNITY_OSX id buf = (__bridge id)bufferHandle; - [buf didModifyRange:NSMakeRange(0, buf.length)]; + if (buf.storageMode == MTLStorageModeManaged) + [buf didModifyRange:NSMakeRange(0, buf.length)]; # endif // if UNITY_OSX } diff --git a/PluginSource/source/RenderAPI_OpenGLCoreES.cpp b/PluginSource/source/RenderAPI_OpenGLCoreES.cpp index 742e4884..5db46cdc 100644 --- a/PluginSource/source/RenderAPI_OpenGLCoreES.cpp +++ b/PluginSource/source/RenderAPI_OpenGLCoreES.cpp @@ -29,6 +29,8 @@ # define GL_GLEXT_PROTOTYPES # include #endif +#elif UNITY_QNX +# include #else # error Unknown platform #endif @@ -137,11 +139,15 @@ static GLuint CreateShader(GLenum type, const char* sourceText) void RenderAPI_OpenGLCoreES::CreateResources() { +# if UNITY_WIN && SUPPORT_OPENGL_CORE + if (m_APIType == kUnityGfxRendererOpenGLCore) + gl3wInit(); +# endif // Make sure that there are no GL error flags set before creating resources while (glGetError() != GL_NO_ERROR) {} // Create shaders - if (m_APIType == kUnityGfxRendererOpenGLES20) + if (m_APIType == kUnityGfxRendererOpenGLES30) { m_VertexShader = CreateShader(GL_VERTEX_SHADER, kGlesVProgTextGLES2); m_FragmentShader = CreateShader(GL_FRAGMENT_SHADER, kGlesFShaderTextGLES2); @@ -154,10 +160,6 @@ void RenderAPI_OpenGLCoreES::CreateResources() # if SUPPORT_OPENGL_CORE else if (m_APIType == kUnityGfxRendererOpenGLCore) { -# if UNITY_WIN - gl3wInit(); -# endif - m_VertexShader = CreateShader(GL_VERTEX_SHADER, kGlesVProgTextGLCore); m_FragmentShader = CreateShader(GL_FRAGMENT_SHADER, kGlesFShaderTextGLCore); } diff --git a/PluginSource/source/RenderAPI_Vulkan.cpp b/PluginSource/source/RenderAPI_Vulkan.cpp index 8e24ca20..8665a1e2 100644 --- a/PluginSource/source/RenderAPI_Vulkan.cpp +++ b/PluginSource/source/RenderAPI_Vulkan.cpp @@ -121,7 +121,7 @@ static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL Hook_vkGetInstanceProcAddr(VkIns INTERCEPT(vkCreateInstance); #undef INTERCEPT - return NULL; + return vkGetInstanceProcAddr(device, funcName); } static PFN_vkGetInstanceProcAddr UNITY_INTERFACE_API InterceptVulkanInitialization(PFN_vkGetInstanceProcAddr getInstanceProcAddr, void*) @@ -749,19 +749,14 @@ void* RenderAPI_Vulkan::BeginModifyVertexBuffer(void* bufferHandle, size_t* outB if (!bufferInfo.memory.mapped) return NULL; - UnityVulkanBuffer src; - if (!m_UnityVulkan->AccessBuffer(bufferHandle, VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_HOST_READ_BIT, kUnityVulkanResourceAccess_PipelineBarrier, &src)) + // We don't want to start modifying a resource that might still be used by the GPU, + // so we can use kUnityVulkanResourceAccess_Recreate to recreate it while still keeping the old one alive if it's in use. + UnityVulkanBuffer recreatedBuffer; + if (!m_UnityVulkan->AccessBuffer(bufferHandle, VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_HOST_WRITE_BIT, kUnityVulkanResourceAccess_Recreate, &recreatedBuffer)) return NULL; - UnityVulkanBuffer dst; - if (!m_UnityVulkan->AccessBuffer(bufferHandle, VK_PIPELINE_STAGE_HOST_BIT, VK_ACCESS_HOST_WRITE_BIT, kUnityVulkanResourceAccess_PipelineBarrier, &dst)) - return NULL; - - // read might be slow because it's not cached - // can't use GPU transfer here because is not marked as transfer src - memcpy(dst.memory.mapped, src.memory.mapped, bufferInfo.sizeInBytes); - - return dst.memory.mapped; + // We don't care about the previous contents of this vertex buffer so we can return the mapped pointer to the new resource memory + return recreatedBuffer.memory.mapped; } void RenderAPI_Vulkan::EndModifyVertexBuffer(void* bufferHandle) diff --git a/PluginSource/source/RenderingPlugin.cpp b/PluginSource/source/RenderingPlugin.cpp index 54af64a0..6b1c5773 100644 --- a/PluginSource/source/RenderingPlugin.cpp +++ b/PluginSource/source/RenderingPlugin.cpp @@ -82,7 +82,6 @@ extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API SetMeshBuffersFromUni } - // -------------------------------------------------------------------------- // UnitySetInterfaces @@ -262,6 +261,13 @@ static void ModifyVertexBuffer() return; int vertexStride = int(bufferSize / vertexCount); + // Unity should return us a buffer that is the size of `vertexCount * sizeof(MeshVertex)` + // If that's not the case then we should quit to avoid unexpected results. + // This can happen if https://docs.unity3d.com/ScriptReference/Mesh.GetNativeVertexBufferPtr.html returns + // a pointer to a buffer with an unexpected layout. + if (static_cast(vertexStride) != sizeof(MeshVertex)) + return; + const float t = g_Time * 3.0f; char* bufferPtr = (char*)bufferDataPtr; @@ -285,6 +291,15 @@ static void ModifyVertexBuffer() s_CurrentAPI->EndModifyVertexBuffer(bufferHandle); } +static void drawToPluginTexture() +{ + s_CurrentAPI->drawToPluginTexture(); +} + +static void drawToRenderTexture() +{ + s_CurrentAPI->drawToRenderTexture(); +} static void UNITY_INTERFACE_API OnRenderEvent(int eventID) { @@ -292,11 +307,20 @@ static void UNITY_INTERFACE_API OnRenderEvent(int eventID) if (s_CurrentAPI == NULL) return; - DrawColoredTriangle(); - ModifyTexturePixels(); - ModifyVertexBuffer(); -} + if (eventID == 1) + { + drawToRenderTexture(); + DrawColoredTriangle(); + ModifyTexturePixels(); + ModifyVertexBuffer(); + } + if (eventID == 2) + { + drawToPluginTexture(); + } + +} // -------------------------------------------------------------------------- // GetRenderEventFunc, an example function we export which is used to get a rendering event callback function. @@ -306,3 +330,41 @@ extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRen return OnRenderEvent; } +// -------------------------------------------------------------------------- +// DX12 plugin specific +// -------------------------------------------------------------------------- + +extern "C" UNITY_INTERFACE_EXPORT void* UNITY_INTERFACE_API GetRenderTexture() +{ + return s_CurrentAPI->getRenderTexture(); +} + +extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API SetRenderTexture(UnityRenderBuffer rb) +{ + s_CurrentAPI->setRenderTextureResource(rb); +} + +extern "C" UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API IsSwapChainAvailable() +{ + return s_CurrentAPI->isSwapChainAvailable(); +} + +extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetPresentFlags() +{ + return s_CurrentAPI->getPresentFlags(); +} + +extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetSyncInterval() +{ + return s_CurrentAPI->getSyncInterval(); +} + +extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetBackBufferWidth() +{ + return s_CurrentAPI->getBackbufferHeight(); +} + +extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetBackBufferHeight() +{ + return s_CurrentAPI->getBackbufferWidth(); +} diff --git a/PluginSource/source/Unity/IUnityGraphics.h b/PluginSource/source/Unity/IUnityGraphics.h index 855009bd..d1f7bf9c 100644 --- a/PluginSource/source/Unity/IUnityGraphics.h +++ b/PluginSource/source/Unity/IUnityGraphics.h @@ -1,16 +1,22 @@ +// 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 - kUnityGfxRendererGCM = 3, // PlayStation 3 kUnityGfxRendererNull = 4, // "null" device (used in batch mode) - kUnityGfxRendererOpenGLES20 = 8, // OpenGL ES 2.0 + //kUnityGfxRendererOpenGLES20 = 8, // OpenGL ES 2.0, removed kUnityGfxRendererOpenGLES30 = 11, // OpenGL ES 3.0 - kUnityGfxRendererGXM = 12, // PlayStation Vita + //kUnityGfxRendererGXM = 12, // PlayStation Vita, removed kUnityGfxRendererPS4 = 13, // PlayStation 4 kUnityGfxRendererXboxOne = 14, // Xbox One kUnityGfxRendererMetal = 16, // iOS Metal @@ -18,7 +24,11 @@ typedef enum UnityGfxRenderer kUnityGfxRendererD3D12 = 18, // Direct3D 12 kUnityGfxRendererVulkan = 21, // Vulkan kUnityGfxRendererNvn = 22, // Nintendo Switch NVN API - kUnityGfxRendererXboxOneD3D12 = 23 // MS XboxOne Direct3D 12 + 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 diff --git a/PluginSource/source/Unity/IUnityGraphicsD3D12.h b/PluginSource/source/Unity/IUnityGraphicsD3D12.h index 00946fd6..3dfdccf9 100644 --- a/PluginSource/source/Unity/IUnityGraphicsD3D12.h +++ b/PluginSource/source/Unity/IUnityGraphicsD3D12.h @@ -1,3 +1,9 @@ +// 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 @@ -15,13 +21,106 @@ struct UnityGraphicsD3D12ResourceState 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 values in bytes +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 residencyThreshold; // Minimum free physical video memory needed to start bringing evicted resources back after shrunken video memory budget expands again. [default = 128MB] + 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) @@ -32,16 +131,16 @@ UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v5) // 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. + // 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. + // 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 * TextureFromRenderBuffer)(UnityRenderBuffer rb); }; UNITY_REGISTER_INTERFACE_GUID(0xF5C8D8A37D37BC42ULL, 0xB02DFE93B5064A27ULL, IUnityGraphicsD3D12v5) @@ -54,9 +153,9 @@ UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v4) // 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. + // 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. + // 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); @@ -74,9 +173,9 @@ UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v3) // 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. + // 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. + // 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); @@ -92,9 +191,9 @@ UNITY_DECLARE_INTERFACE(IUnityGraphicsD3D12v2) // 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. + // 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. + // 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) diff --git a/PluginSource/source/Unity/IUnityInterface.h b/PluginSource/source/Unity/IUnityInterface.h index 190c5a02..ab713ec6 100644 --- a/PluginSource/source/Unity/IUnityInterface.h +++ b/PluginSource/source/Unity/IUnityInterface.h @@ -1,3 +1,9 @@ +// 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 @@ -9,9 +15,9 @@ #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__) +#elif defined(__MACH__) || defined(__ANDROID__) || defined(__linux__) || defined(LUMIN) #define UNITY_INTERFACE_API - #define UNITY_INTERFACE_EXPORT + #define UNITY_INTERFACE_EXPORT __attribute__ ((visibility ("default"))) #else #define UNITY_INTERFACE_API #define UNITY_INTERFACE_EXPORT diff --git a/README.md b/README.md index c7f77ca1..67cd950f 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,7 @@ This sample demonstrates how to render and do other graphics related things from Unity versions: -* **2018.1+** use tip of default branch. -* 5.6, 5.5, 5.4: use corresponding `unity-x.x` tag. +* **2023.1+** use tip of default branch. The plugin itself does very few things: @@ -22,27 +21,31 @@ The plugin itself does very few things: Native code rendering is implemented for several platforms and graphics APIs: * Windows (D3D11, D3D12, OpenGL, Vulkan) - * Note that Vulkan is not compiled in by default (requires Vulkan SDK); enable it by editing `#define SUPPORT_VULKAN 0` + * Note that Vulkan and DX12 are not compiled in by default + * Vulkan requires Vulkan SDK; enable it by editing `#define SUPPORT_VULKAN 0` to `1` under `UNITY_WIN` clause in `PlatformBase.h` + * DX12 requires additional header files (see on [github](https://github.com/microsoft/DirectX-Headers) or [nuget package](https://www.nuget.org/packages/Microsoft.Direct3D.D3D12/1.4.10)); enable it by editing `#define SUPPORT_D3D12 0` to `1` under `UNITY_WIN` clause in `PlatformBase.h` * macOS (Metal, OpenGL) * Linux (OpenGL, Vulkan) * Windows Store aka UWP (D3D11, D3D12) * WebGL (OpenGL ES) * Android (OpenGL ES, Vulkan) * iOS/tvOS (Metal; Simulator is supported if you use unity 2020+ and XCode 11+) -* EmbeddedLinux (OpenGL, Open GLES) +* EmbeddedLinux (OpenGL, OpenGL ES , Vulkan) +* QNX (OpenGL ES) * ...more platforms might be coming soon, we just did not get around to adding project files yet. Code is organized as follows: * `PluginSource` is source code & IDE project files for the C++ plugin. * `source`: The source code itself. `RenderingPlugin.cpp` is the main logic, `RenderAPI*.*` files contain rendering implementations for different APIs. - * `projects/VisualStudio2015`: Visual Studio 2015 project files for regular Windows plugin - * `projects/UWPVisualStudio2015`: Visual Studio 2015 project files for Windows Store (UWP - Win10) plugin + * `projects/VisualStudio2022`: Visual Studio 2022 project files for regular Windows plugin + * `projects/UWPVisualStudio2022`: Visual Studio 2022 project files for Windows Store (UWP) plugin * `projects/Xcode`: Apple Xcode project file for Mac OS X plugin, Xcode 10.3 on macOS 10.14 was tested * `projects/GNUMake`: Makefile for Linux * `projects/EmbeddedLinux`: Windows .bat files to build plugins for different architectures -* `UnityProject` is the Unity (2018.3.9 was tested) project. + * `projects/QNX`: Makefile for Linux requires QNX to be installed and environment variables to be set +* `UnityProject` is the Unity (2023.1.15f1 was tested) project. * Single `scene` that contains the plugin sample scene. diff --git a/UnityProject/Assets/Plugins/Metro/UWP/x64/RenderingPlugin.dll b/UnityProject/Assets/Plugins/Metro/UWP/x64/RenderingPlugin.dll index b3c5879a..25fe78a0 100644 Binary files a/UnityProject/Assets/Plugins/Metro/UWP/x64/RenderingPlugin.dll and b/UnityProject/Assets/Plugins/Metro/UWP/x64/RenderingPlugin.dll differ diff --git a/UnityProject/Assets/Plugins/Metro/UWP/x86/RenderingPlugin.dll b/UnityProject/Assets/Plugins/Metro/UWP/x86/RenderingPlugin.dll index 37b06990..345e8b93 100644 Binary files a/UnityProject/Assets/Plugins/Metro/UWP/x86/RenderingPlugin.dll and b/UnityProject/Assets/Plugins/Metro/UWP/x86/RenderingPlugin.dll differ diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents.meta b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents.meta deleted file mode 100644 index 74ed6185..00000000 --- a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f755e08657c4d45a2964c48ee8fe540d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist index 8eed89a2..905d9e17 100644 --- a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist +++ b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist @@ -3,7 +3,7 @@ BuildMachineOSBuild - 18G87 + 25F84 CFBundleDevelopmentRegion English CFBundleExecutable @@ -47,16 +47,20 @@ DTCompiler com.apple.compilers.llvm.clang.1_0 DTPlatformBuild - 10G8 + 25F70 + DTPlatformName + macosx DTPlatformVersion - GM + 26.5 DTSDKBuild - 18G74 + 25F70 DTSDKName - macosx10.14 + macosx26.5 DTXcode - 1030 + 2660 DTXcodeBuild - 10G8 + 17F113 + LSMinimumSystemVersion + 13.0 diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist.meta b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist.meta deleted file mode 100644 index 0476b6af..00000000 --- a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/Info.plist.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 8aa00d77c9d59498d8afc6cc966ccedf -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS.meta b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS.meta deleted file mode 100644 index 4d9bf1d4..00000000 --- a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ea416e3a931c44c7dab7be3ff85af5da -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin index ffed025a..590c51c5 100755 Binary files a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin and b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin differ diff --git a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin.meta b/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin.meta deleted file mode 100644 index 488164d4..00000000 --- a/UnityProject/Assets/Plugins/RenderingPlugin.bundle/Contents/MacOS/RenderingPlugin.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: f0b092cc71f8b465cbb5a657186a3267 -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/x86/RenderingPlugin.dll b/UnityProject/Assets/Plugins/x86/RenderingPlugin.dll index 83dfd6ab..1630de08 100644 Binary files a/UnityProject/Assets/Plugins/x86/RenderingPlugin.dll and b/UnityProject/Assets/Plugins/x86/RenderingPlugin.dll differ diff --git a/UnityProject/Assets/Plugins/x86_64/RenderingPlugin.dll b/UnityProject/Assets/Plugins/x86_64/RenderingPlugin.dll index dd91c588..eb3eecff 100644 Binary files a/UnityProject/Assets/Plugins/x86_64/RenderingPlugin.dll and b/UnityProject/Assets/Plugins/x86_64/RenderingPlugin.dll differ diff --git a/UnityProject/Assets/UseRenderingPlugin.cs b/UnityProject/Assets/UseRenderingPlugin.cs index 97fcbc39..ceea22e1 100644 --- a/UnityProject/Assets/UseRenderingPlugin.cs +++ b/UnityProject/Assets/UseRenderingPlugin.cs @@ -2,130 +2,212 @@ using System; using System.Collections; using System.Runtime.InteropServices; +using UnityEngine.Rendering; public class UseRenderingPlugin : MonoBehaviour { - // Native plugin rendering events are only called if a plugin is used - // by some script. This means we have to DllImport at least - // one function in some active script. - // For this example, we'll call into plugin's SetTimeFromUnity - // function and pass the current time so the plugin can animate. - -#if (UNITY_IOS || UNITY_TVOS || UNITY_WEBGL) && !UNITY_EDITOR - [DllImport ("__Internal")] + // Native plugin rendering events are only called if a plugin is used + // by some script. This means we have to DllImport at least + // one function in some active script. + // For this example, we'll call into plugin's SetTimeFromUnity + // function and pass the current time so the plugin can animate. + +#if (PLATFORM_IOS || PLATFORM_TVOS || PLATFORM_BRATWURST || PLATFORM_SWITCH) && !UNITY_EDITOR + [DllImport("__Internal")] #else - [DllImport ("RenderingPlugin")] + [DllImport("RenderingPlugin")] #endif - private static extern void SetTimeFromUnity(float t); + private static extern void SetTimeFromUnity(float t); - // We'll also pass native pointer to a texture in Unity. - // The plugin will fill texture data from native code. -#if (UNITY_IOS || UNITY_TVOS || UNITY_WEBGL) && !UNITY_EDITOR - [DllImport ("__Internal")] + // We'll also pass native pointer to a texture in Unity. + // The plugin will fill texture data from native code. +#if (PLATFORM_IOS || PLATFORM_TVOS || PLATFORM_BRATWURST || PLATFORM_SWITCH) && !UNITY_EDITOR + [DllImport("__Internal")] #else - [DllImport ("RenderingPlugin")] + [DllImport("RenderingPlugin")] #endif - private static extern void SetTextureFromUnity(System.IntPtr texture, int w, int h); + private static extern void SetTextureFromUnity(System.IntPtr texture, int w, int h); - // We'll pass native pointer to the mesh vertex buffer. - // Also passing source unmodified mesh data. - // The plugin will fill vertex data from native code. -#if (UNITY_IOS || UNITY_TVOS || UNITY_WEBGL) && !UNITY_EDITOR - [DllImport ("__Internal")] + // We'll pass native pointer to the mesh vertex buffer. + // Also passing source unmodified mesh data. + // The plugin will fill vertex data from native code. +#if (PLATFORM_IOS || PLATFORM_TVOS || PLATFORM_BRATWURST || PLATFORM_SWITCH) && !UNITY_EDITOR + [DllImport("__Internal")] #else - [DllImport ("RenderingPlugin")] + [DllImport("RenderingPlugin")] #endif - private static extern void SetMeshBuffersFromUnity (IntPtr vertexBuffer, int vertexCount, IntPtr sourceVertices, IntPtr sourceNormals, IntPtr sourceUVs); + private static extern void SetMeshBuffersFromUnity(IntPtr vertexBuffer, int vertexCount, IntPtr sourceVertices, IntPtr sourceNormals, IntPtr sourceUVs); -#if (UNITY_IOS || UNITY_TVOS || UNITY_WEBGL) && !UNITY_EDITOR - [DllImport ("__Internal")] +#if (PLATFORM_IOS || PLATFORM_TVOS || PLATFORM_BRATWURST || PLATFORM_SWITCH) && !UNITY_EDITOR + [DllImport("__Internal")] #else - [DllImport("RenderingPlugin")] + [DllImport("RenderingPlugin")] #endif - private static extern IntPtr GetRenderEventFunc(); + private static extern IntPtr GetRenderEventFunc(); -#if UNITY_WEBGL && !UNITY_EDITOR - [DllImport ("__Internal")] - private static extern void RegisterPlugin(); +#if PLATFORM_SWITCH && !UNITY_EDITOR + [DllImport("__Internal")] + private static extern void RegisterPlugin(); #endif - IEnumerator Start() - { -#if UNITY_WEBGL && !UNITY_EDITOR - RegisterPlugin(); + // DX12 plugin has a few additional exported functions + +#if (UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_WSA || UNITY_WSA_10_0) + [DllImport("RenderingPlugin")] + private static extern IntPtr GetRenderTexture(); + + [DllImport("RenderingPlugin")] + private static extern void SetRenderTexture(IntPtr rb); + + [DllImport("RenderingPlugin")] + private static extern bool IsSwapChainAvailable(); + + [DllImport("RenderingPlugin")] + private static extern uint GetPresentFlags(); + + [DllImport("RenderingPlugin")] + private static extern uint GetBackBufferWidth(); + + [DllImport("RenderingPlugin")] + private static extern uint GetSyncInterval(); + + [DllImport("RenderingPlugin")] + private static extern uint GetBackBufferHeight(); + + private static RenderTexture renderTex; + private static GameObject pluginInfo; + + private void CreateRenderTexture() + { + renderTex = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32); + renderTex.Create(); + IntPtr nativeBufPTr = renderTex.colorBuffer.GetNativeRenderBufferPtr(); + SetRenderTexture(nativeBufPTr); + GameObject sphere = GameObject.Find("Sphere"); + sphere.transform.rotation = Quaternion.Euler(0.0f, 180.0f, 0.0f); + sphere.GetComponent().material.mainTexture = renderTex; + } + +#else + private void CreateRenderTexture() { } + private void SetRenderTexture(IntPtr rb) { } #endif - CreateTextureAndPassToPlugin(); - SendMeshBuffersToPlugin(); - yield return StartCoroutine("CallPluginAtEndOfFrames"); - } - - private void CreateTextureAndPassToPlugin() - { - // Create a texture - Texture2D tex = new Texture2D(256,256,TextureFormat.ARGB32,false); - // Set point filtering just so we can see the pixels clearly - tex.filterMode = FilterMode.Point; - // Call Apply() so it's actually uploaded to the GPU - tex.Apply(); - - // Set texture onto our material - GetComponent().material.mainTexture = tex; - - // Pass texture pointer to the plugin - SetTextureFromUnity (tex.GetNativeTexturePtr(), tex.width, tex.height); - } - - private void SendMeshBuffersToPlugin () - { - var filter = GetComponent (); - var mesh = filter.mesh; - // The plugin will want to modify the vertex buffer -- on many platforms - // for that to work we have to mark mesh as "dynamic" (which makes the buffers CPU writable -- - // by default they are immutable and only GPU-readable). - mesh.MarkDynamic (); - - // Make sure to have vertex colors so that the plugin can rely on a known - // vertex layout (position+normal+color+UV). Since Unity 2019.3 it's easier - // since there are APIs to query all that info. - var colors = mesh.colors; - mesh.colors = colors; - - // However, mesh being dynamic also means that the CPU on most platforms can not - // read from the vertex buffer. Our plugin also wants original mesh data, - // so let's pass it as pointers to regular C# arrays. - // This bit shows how to pass array pointers to native plugins without doing an expensive - // copy: you have to get a GCHandle, and get raw address of that. - var vertices = mesh.vertices; - var normals = mesh.normals; - var uvs = mesh.uv; - GCHandle gcVertices = GCHandle.Alloc (vertices, GCHandleType.Pinned); - GCHandle gcNormals = GCHandle.Alloc (normals, GCHandleType.Pinned); - GCHandle gcUV = GCHandle.Alloc (uvs, GCHandleType.Pinned); - - SetMeshBuffersFromUnity (mesh.GetNativeVertexBufferPtr (0), mesh.vertexCount, gcVertices.AddrOfPinnedObject (), gcNormals.AddrOfPinnedObject (), gcUV.AddrOfPinnedObject ()); - - gcVertices.Free (); - gcNormals.Free (); - gcUV.Free (); - } - - - private IEnumerator CallPluginAtEndOfFrames() - { - while (true) { - // Wait until all frame rendering is done - yield return new WaitForEndOfFrame(); - - // Set time for the plugin - SetTimeFromUnity (Time.timeSinceLevelLoad); - - // Issue a plugin event with arbitrary integer identifier. - // The plugin can distinguish between different - // things it needs to do based on this ID. - // For our simple plugin, it does not matter which ID we pass here. - GL.IssuePluginEvent(GetRenderEventFunc(), 1); - } - } + + IEnumerator Start() + { +#if PLATFORM_SWITCH && !UNITY_EDITOR + RegisterPlugin(); +#endif + + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12) + { + CreateRenderTexture(); + } + + CreateTextureAndPassToPlugin(); + SendMeshBuffersToPlugin(); + yield return StartCoroutine("CallPluginAtEndOfFrames"); + } + + void OnDisable() + { + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12) + { + // Signals the plugin that renderTex will be destroyed + SetRenderTexture(IntPtr.Zero); + } + } + + private void CreateTextureAndPassToPlugin() + { + // Create a texture + Texture2D tex = new Texture2D(256, 256, TextureFormat.ARGB32, false); + // Set point filtering just so we can see the pixels clearly + tex.filterMode = FilterMode.Point; + // Call Apply() so it's actually uploaded to the GPU + tex.Apply(); + + // Set texture onto our material + GetComponent().material.mainTexture = tex; + + // Pass texture pointer to the plugin + SetTextureFromUnity(tex.GetNativeTexturePtr(), tex.width, tex.height); + } + + private void SendMeshBuffersToPlugin() + { + var filter = GetComponent(); + var mesh = filter.mesh; + + // This is equivalent to MeshVertex in RenderingPlugin.cpp + var desiredVertexLayout = new[] + { + new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3), + new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3), + new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, 4), + new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2) + }; + + // Let's be certain we'll get the vertex buffer layout we want in native code + mesh.SetVertexBufferParams(mesh.vertexCount, desiredVertexLayout); + + // The plugin will want to modify the vertex buffer -- on many platforms + // for that to work we have to mark mesh as "dynamic" (which makes the buffers CPU writable -- + // by default they are immutable and only GPU-readable). + mesh.MarkDynamic(); + + // However, mesh being dynamic also means that the CPU on most platforms can not + // read from the vertex buffer. Our plugin also wants original mesh data, + // so let's pass it as pointers to regular C# arrays. + // This bit shows how to pass array pointers to native plugins without doing an expensive + // copy: you have to get a GCHandle, and get raw address of that. + var vertices = mesh.vertices; + var normals = mesh.normals; + var uvs = mesh.uv; + GCHandle gcVertices = GCHandle.Alloc(vertices, GCHandleType.Pinned); + GCHandle gcNormals = GCHandle.Alloc(normals, GCHandleType.Pinned); + GCHandle gcUV = GCHandle.Alloc(uvs, GCHandleType.Pinned); + + SetMeshBuffersFromUnity(mesh.GetNativeVertexBufferPtr(0), mesh.vertexCount, gcVertices.AddrOfPinnedObject(), gcNormals.AddrOfPinnedObject(), gcUV.AddrOfPinnedObject()); + + gcVertices.Free(); + gcNormals.Free(); + gcUV.Free(); + } + + // custom "time" for deterministic results + int updateTimeCounter = 0; + + private IEnumerator CallPluginAtEndOfFrames() + { + while (true) + { + // Wait until all frame rendering is done + yield return new WaitForEndOfFrame(); + + // Set time for the plugin + // Unless it is D3D12 whose renderer is allowed to overlap with the next frame update and would cause instabilities due to no synchronization. + // On Switch, with multithreaded mode, setting the time for frame 1 may overlap with the render thread calling the plugin event for frame 0 resulting in the plugin writing data for frame 1 at frame 0. + if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Direct3D12 && SystemInfo.graphicsDeviceType != GraphicsDeviceType.Switch) + { + ++updateTimeCounter; + SetTimeFromUnity((float)updateTimeCounter * 0.016f); + } + + // Issue a plugin event with arbitrary integer identifier. + // The plugin can distinguish between different + // things it needs to do based on this ID. + // On some backends the choice of eventID matters e.g on DX12 where + // eventID == 1 means the plugin callback will be called from the render thread + // and eventID == 2 means the callback is called from the submission thread + GL.IssuePluginEvent(GetRenderEventFunc(), 1); + + if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12) + { + GL.IssuePluginEvent(GetRenderEventFunc(), 2); + } + } + } } diff --git a/UnityProject/Assets/scene.unity b/UnityProject/Assets/scene.unity index f74696dc..69c1ee60 100644 --- a/UnityProject/Assets/scene.unity +++ b/UnityProject/Assets/scene.unity @@ -1,19 +1,19 @@ %YAML 1.1 %TAG !u! tag:unity3d.com,2011: --- !u!29 &1 -SceneSettings: +OcclusionCullingSettings: m_ObjectHideFlags: 0 - m_PVSData: - m_PVSObjectsArray: [] - m_PVSPortalsArray: [] + serializedVersion: 2 m_OcclusionBakeSettings: smallestOccluder: 5 smallestHole: 0.25 backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} --- !u!104 &2 RenderSettings: m_ObjectHideFlags: 0 - serializedVersion: 7 + serializedVersion: 9 m_Fog: 0 m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} m_FogMode: 3 @@ -25,6 +25,7 @@ RenderSettings: m_AmbientGroundColor: {r: 0.098908, g: 0.100485, b: 0.119403, a: 1} m_AmbientIntensity: 1 m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} m_SkyboxMaterial: {fileID: 0} m_HaloStrength: 0.5 m_FlareStrength: 1 @@ -38,70 +39,100 @@ RenderSettings: m_CustomReflection: {fileID: 0} m_Sun: {fileID: 0} m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 --- !u!157 &4 LightmapSettings: m_ObjectHideFlags: 0 - serializedVersion: 7 + serializedVersion: 12 m_GIWorkflowMode: 1 m_GISettings: serializedVersion: 2 m_BounceScale: 1 m_IndirectOutputScale: 1 m_AlbedoBoost: 1 - m_TemporalCoherenceThreshold: 1 m_EnvironmentLightingMode: 0 m_EnableBakedLightmaps: 1 m_EnableRealtimeLightmaps: 0 m_LightmapEditorSettings: - serializedVersion: 4 + serializedVersion: 12 m_Resolution: 1 m_BakeResolution: 50 - m_TextureWidth: 1024 - m_TextureHeight: 1024 + m_AtlasSize: 1024 m_AO: 1 m_AOMaxDistance: 1 m_CompAOExponent: 1 m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 m_Padding: 2 m_LightmapParameters: {fileID: 0} m_LightmapsBakeMode: 1 m_TextureCompression: 0 - m_DirectLightInLightProbes: 1 - m_FinalGather: 0 - m_FinalGatherFiltering: 1 - m_FinalGatherRayCount: 256 m_ReflectionCompression: 2 + m_MixedBakeMode: 1 + m_BakeBackend: 0 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 512 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 0 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 m_LightingDataAsset: {fileID: 0} - m_RuntimeCPUUsage: 25 + m_LightingSettings: {fileID: 4890085278179872738, guid: ce9c18af04d795548bfbfde3a9fcb6ea, + type: 2} --- !u!196 &5 NavMeshSettings: serializedVersion: 2 m_ObjectHideFlags: 0 m_BuildSettings: - serializedVersion: 2 + serializedVersion: 3 + agentTypeID: 0 agentRadius: 0.4 agentHeight: 1.8 agentSlope: 45 agentClimb: 0.9 ledgeDropHeight: 0 maxJumpAcrossDistance: 0 - accuratePlacement: 0 minRegionArea: 2 - cellSize: 0.13333333 manualCellSize: 0 + cellSize: 0.13333333 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 m_NavMeshData: {fileID: 0} --- !u!1 &7 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - 4: {fileID: 9} - - 20: {fileID: 10} - - 92: {fileID: 12} - - 124: {fileID: 13} - - 81: {fileID: 11} + - component: {fileID: 9} + - component: {fileID: 10} + - component: {fileID: 13} + - component: {fileID: 11} m_Layer: 0 m_Name: Main Camera m_TagString: MainCamera @@ -112,26 +143,43 @@ GameObject: --- !u!4 &9 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7} + serializedVersion: 2 m_LocalRotation: {x: -0.13691497, y: -0.8374118, z: 0.24425894, w: -0.4693969} m_LocalPosition: {x: -1.913136, y: 2.253977, z: 0.506491} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!20 &10 Camera: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7} m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 1 m_BackGroundColor: {r: 0.192157, g: 0.301961, b: 0.47451, a: 0.019608} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_Iso: 200 + m_ShutterSpeed: 0.005 + m_Aperture: 16 + m_FocusDistance: 10 + m_FocalLength: 50 + m_BladeCount: 5 + m_Curvature: {x: 2, y: 11} + m_BarrelClipping: 0.25 + m_Anamorphism: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} m_NormalizedViewPortRect: serializedVersion: 2 x: 0 @@ -152,40 +200,38 @@ Camera: m_TargetDisplay: 0 m_TargetEye: 3 m_HDR: 0 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 m_OcclusionCulling: 1 m_StereoConvergence: 10 m_StereoSeparation: 0.022 - m_StereoMirrorMode: 0 --- !u!81 &11 AudioListener: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 7} - m_Enabled: 1 ---- !u!92 &12 -Behaviour: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7} m_Enabled: 1 --- !u!124 &13 Behaviour: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 7} m_Enabled: 1 --- !u!1 &15 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - 4: {fileID: 19} - - 108: {fileID: 28} + - component: {fileID: 19} + - component: {fileID: 28} m_Layer: 0 m_Name: Spotlight m_TagString: Untagged @@ -196,12 +242,13 @@ GameObject: --- !u!1 &16 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - 4: {fileID: 20} - - 108: {fileID: 29} + - component: {fileID: 20} + - component: {fileID: 29} m_Layer: 0 m_Name: Directional light m_TagString: Untagged @@ -212,13 +259,14 @@ GameObject: --- !u!1 &17 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - 4: {fileID: 21} - - 33: {fileID: 25} - - 23: {fileID: 23} + - component: {fileID: 21} + - component: {fileID: 25} + - component: {fileID: 23} m_Layer: 0 m_Name: Sphere m_TagString: Untagged @@ -229,14 +277,15 @@ GameObject: --- !u!1 &18 GameObject: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 m_Component: - - 4: {fileID: 22} - - 33: {fileID: 26} - - 23: {fileID: 24} - - 114: {fileID: 31} + - component: {fileID: 22} + - component: {fileID: 26} + - component: {fileID: 24} + - component: {fileID: 31} m_Layer: 0 m_Name: _PlaneThatCallsIntoPlugin m_TagString: Untagged @@ -247,148 +296,206 @@ GameObject: --- !u!4 &19 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 15} + serializedVersion: 2 m_LocalRotation: {x: -0.08680297, y: -0.9131517, z: 0.27678692, w: -0.2863709} m_LocalPosition: {x: -2.210178, y: 2.850663, z: 1.878642} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 5 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &20 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 16} + serializedVersion: 2 m_LocalRotation: {x: -0.31668198, y: -0.33227497, z: 0.119525984, w: -0.8803519} m_LocalPosition: {x: -2.359002, y: 3.204721, z: -3.580904} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &21 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 17} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0.109563, y: 1.027012, z: -1.076521} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 4 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!4 &22 Transform: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 18} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 1.9431487, y: 0.447558, z: -3.4134645} m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 0} - m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!23 &23 MeshRenderer: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 17} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 m_Materials: - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 + m_SortingLayer: 0 m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!23 &24 MeshRenderer: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 18} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 m_MotionVectors: 1 m_LightProbeUsage: 0 m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 m_Materials: - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0} - m_SubsetIndices: + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 m_StaticBatchRoot: {fileID: 0} m_ProbeAnchor: {fileID: 0} m_LightProbeVolumeOverride: {fileID: 0} m_ScaleInLightmap: 1 + m_ReceiveGI: 1 m_PreserveUVs: 0 m_IgnoreNormalsForChartDetection: 0 m_ImportantGI: 0 - m_SelectedWireframeHidden: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 m_MinimumChartSize: 4 m_AutoUVMaxDistance: 0.5 m_AutoUVMaxAngle: 89 m_LightmapParameters: {fileID: 0} m_SortingLayerID: 0 + m_SortingLayer: 0 m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} --- !u!33 &25 MeshFilter: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 17} m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} --- !u!33 &26 MeshFilter: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 18} m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} --- !u!108 &28 Light: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 15} m_Enabled: 1 - serializedVersion: 7 + serializedVersion: 10 m_Type: 0 + m_Shape: 0 m_Color: {r: 1, g: 0.492537, b: 0.492537, a: 1} m_Intensity: 2 m_Range: 10 m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 m_CookieSize: 10 m_Shadows: m_Type: 0 m_Resolution: -1 + m_CustomResolution: -1 m_Strength: 1 m_Bias: 0.05 m_NormalBias: 0.4 m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 m_Cookie: {fileID: 0} m_DrawHalo: 0 m_Flare: {fileID: 0} @@ -396,32 +503,61 @@ Light: m_CullingMask: serializedVersion: 2 m_Bits: 4294967295 + m_RenderingLayerMask: 1 m_Lightmapping: 1 + m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 m_ShadowRadius: 0 m_ShadowAngle: 0 --- !u!108 &29 Light: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 16} m_Enabled: 1 - serializedVersion: 7 + serializedVersion: 10 m_Type: 1 + m_Shape: 0 m_Color: {r: 1, g: 0.997495, b: 0.955224, a: 1} m_Intensity: 1 m_Range: 10 m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 m_CookieSize: 10 m_Shadows: m_Type: 2 m_Resolution: -1 + m_CustomResolution: -1 m_Strength: 1 m_Bias: 0.05 m_NormalBias: 0.4 m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 m_Cookie: {fileID: 0} m_DrawHalo: 0 m_Flare: {fileID: 0} @@ -429,73 +565,36 @@ Light: m_CullingMask: serializedVersion: 2 m_Bits: 4294967295 + m_RenderingLayerMask: 1 m_Lightmapping: 1 + m_LightShadowCasterMode: 0 m_AreaSize: {x: 1, y: 1} m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 m_ShadowRadius: 0 m_ShadowAngle: 0 --- !u!114 &31 MonoBehaviour: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 18} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: f1ad34d2576df73428a8586fc566c6cb, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1 &32 -GameObject: +--- !u!1660057539 &9223372036854775807 +SceneRoots: m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - serializedVersion: 4 - m_Component: - - 4: {fileID: 33} - - 132: {fileID: 34} - m_Layer: 0 - m_Name: GUI Text Instructions - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &33 -Transform: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 32} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 1, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_Children: [] - m_Father: {fileID: 0} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!132 &34 -GUIText: - m_ObjectHideFlags: 0 - m_PrefabParentObject: {fileID: 0} - m_PrefabInternal: {fileID: 0} - m_GameObject: {fileID: 32} - m_Enabled: 1 - serializedVersion: 3 - m_Text: "A simple scene. The plugin will render a rotating triangle in the middle - of it.\r\nIt will also fill the plane texture each frame.\r\nAnd modify the plane - vertex buffer each frame.\nAll done from native code.\r\nPress Play!" - m_Anchor: 0 - m_Alignment: 0 - m_PixelOffset: {x: 0, y: 0} - m_LineSpacing: 1 - m_TabSize: 4 - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_Material: {fileID: 0} - m_FontSize: 0 - m_FontStyle: 0 - m_Color: - serializedVersion: 2 - rgba: 4294967295 - m_PixelCorrect: 1 - m_RichText: 1 + m_Roots: + - {fileID: 22} + - {fileID: 9} + - {fileID: 20} + - {fileID: 21} + - {fileID: 19} diff --git a/UnityProject/Packages/manifest.json b/UnityProject/Packages/manifest.json index 950f1abe..3a39d617 100644 --- a/UnityProject/Packages/manifest.json +++ b/UnityProject/Packages/manifest.json @@ -1,8 +1,17 @@ { "dependencies": { - "com.unity.package-manager-ui": "2.0.7", - "com.unity.textmeshpro": "1.4.1", + "com.unity.2d.sprite": "1.0.0", + "com.unity.2d.tilemap": "1.0.0", + "com.unity.ai.navigation": "1.1.4", + "com.unity.ide.rider": "3.0.24", + "com.unity.ide.visualstudio": "2.0.18", + "com.unity.test-framework": "1.3.9", + "com.unity.textmeshpro": "3.0.6", + "com.unity.timeline": "1.8.2", + "com.unity.ugui": "1.0.0", + "com.unity.xr.legacyinputhelpers": "2.1.10", "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", "com.unity.modules.animation": "1.0.0", "com.unity.modules.assetbundle": "1.0.0", "com.unity.modules.audio": "1.0.0", diff --git a/UnityProject/ProjectSettings/EditorBuildSettings.asset b/UnityProject/ProjectSettings/EditorBuildSettings.asset index 6dc24f7d..add5036a 100644 --- a/UnityProject/ProjectSettings/EditorBuildSettings.asset +++ b/UnityProject/ProjectSettings/EditorBuildSettings.asset @@ -4,4 +4,9 @@ EditorBuildSettings: m_ObjectHideFlags: 0 serializedVersion: 2 - m_Scenes: [] + m_Scenes: + - enabled: 1 + path: Assets/scene.unity + guid: c159f2591a9b5c843b0a0442451f78f8 + m_configObjects: {} + m_UseUCBPForAssetBundles: 0 diff --git a/UnityProject/ProjectSettings/ProjectVersion.txt b/UnityProject/ProjectSettings/ProjectVersion.txt index 1d735178..93aa152b 100644 --- a/UnityProject/ProjectSettings/ProjectVersion.txt +++ b/UnityProject/ProjectSettings/ProjectVersion.txt @@ -1 +1,2 @@ -m_EditorVersion: 2018.3.9f1 +m_EditorVersion: 2023.1.15f1 +m_EditorVersionWithRevision: 2023.1.15f1 (831263a4172c)