mirror of
				https://github.com/hedge-dev/UnleashedRecomp.git
				synced 2025-10-30 07:11:05 +00:00 
			
		
		
		
	Compare commits
	
		
			5 commits
		
	
	
		
			9fb821ed31
			...
			a9c9b808ba
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a9c9b808ba | ||
|   | 3c1badf183 | ||
|   | 9ace79a4d2 | ||
|   | 80e779afd9 | ||
|   | 78564d4c1f | 
					 58 changed files with 846 additions and 11854 deletions
				
			
		
							
								
								
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -210,3 +210,80 @@ jobs: | |||
|         with: | ||||
|           name: UnleashedRecomp-Flatpak | ||||
|           path: ./${{ env.FLATPAK_ID }}.flatpak | ||||
|   build-macos: | ||||
|     name: Build macOS | ||||
|     runs-on: macos-15 | ||||
|     strategy: | ||||
|       matrix: | ||||
|         arch: [ "arm64" ] | ||||
|         preset: ["macos-debug", "macos-release", "macos-relwithdebinfo"] | ||||
|     env: | ||||
|       CMAKE_PRESET: ${{ matrix.preset }} | ||||
| 
 | ||||
|     steps: | ||||
|       - name: Checkout Repository | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           submodules: recursive | ||||
| 
 | ||||
|       - name: Checkout Private Repository | ||||
|         uses: actions/checkout@v4 | ||||
|         with: | ||||
|           repository: ${{ secrets.ASSET_REPO }} | ||||
|           token: ${{ secrets.ASSET_REPO_TOKEN }} | ||||
|           path: ./private | ||||
| 
 | ||||
|       - name: Setup latest Xcode | ||||
|         uses: maxim-lobanov/setup-xcode@v1 | ||||
|         with: | ||||
|           xcode-version: latest-stable | ||||
| 
 | ||||
|       - name: Setup ccache | ||||
|         uses: hendrikmuhs/ccache-action@v1.2 | ||||
|         with: | ||||
|           key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }} | ||||
| 
 | ||||
|       - name: Cache vcpkg | ||||
|         uses: actions/cache@v4 | ||||
|         with: | ||||
|           path: | | ||||
|             ./thirdparty/vcpkg/downloads | ||||
|             ./thirdparty/vcpkg/packages | ||||
|           key: vcpkg-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }} | ||||
|           restore-keys: | | ||||
|             vcpkg-${{ runner.os }}-${{ matrix.arch }}- | ||||
| 
 | ||||
|       - name: Install Dependencies (macOS) | ||||
|         run: | | ||||
|           brew install ninja | ||||
| 
 | ||||
|       - name: Cache ccache Directory | ||||
|         uses: actions/cache@v4 | ||||
|         with: | ||||
|           path: /tmp/ccache | ||||
|           key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }} | ||||
| 
 | ||||
|       - name: Prepare Project | ||||
|         run: | | ||||
|           cp ./private/* ./UnleashedRecompLib/private | ||||
| 
 | ||||
|       - name: Configure Project | ||||
|         env: | ||||
|           CCACHE_DIR: /tmp/ccache | ||||
|         run: cmake . --preset ${{ env.CMAKE_PRESET }} -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} -DSDL2MIXER_VORBIS=VORBISFILE -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache | ||||
| 
 | ||||
|       - name: Build Project | ||||
|         env: | ||||
|           CCACHE_DIR: /tmp/ccache | ||||
|         run: cmake --build ./out/build/${{ env.CMAKE_PRESET }} --target UnleashedRecomp | ||||
| 
 | ||||
|       - name: Pack Release | ||||
|         run: | | ||||
|           codesign --deep -fs - "./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp/Unleashed Recompiled.app" | ||||
|           tar -czf UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz -C ./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp "Unleashed Recompiled.app" | ||||
| 
 | ||||
|       - name: Upload Artifact | ||||
|         uses: actions/upload-artifact@v4 | ||||
|         with: | ||||
|           name: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }} | ||||
|           path: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz | ||||
|  |  | |||
							
								
								
									
										21
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							|  | @ -16,21 +16,9 @@ | |||
| [submodule "thirdparty/vcpkg"] | ||||
| 	path = thirdparty/vcpkg | ||||
| 	url = https://github.com/microsoft/vcpkg | ||||
| [submodule "thirdparty/volk"] | ||||
| 	path = thirdparty/volk | ||||
| 	url = https://github.com/zeux/volk | ||||
| [submodule "thirdparty/SDL"] | ||||
| 	path = thirdparty/SDL | ||||
| 	url = https://github.com/libsdl-org/SDL.git | ||||
| [submodule "thirdparty/Vulkan-Headers"] | ||||
| 	path = thirdparty/Vulkan-Headers | ||||
| 	url = https://github.com/KhronosGroup/Vulkan-Headers.git | ||||
| [submodule "thirdparty/VulkanMemoryAllocator"] | ||||
| 	path = thirdparty/VulkanMemoryAllocator | ||||
| 	url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git | ||||
| [submodule "thirdparty/D3D12MemoryAllocator"] | ||||
| 	path = thirdparty/D3D12MemoryAllocator | ||||
| 	url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git | ||||
| [submodule "thirdparty/stb"] | ||||
| 	path = thirdparty/stb | ||||
| 	url = https://github.com/nothings/stb.git | ||||
|  | @ -61,3 +49,12 @@ | |||
| [submodule "UnleashedRecomp/api"] | ||||
| 	path = UnleashedRecomp/api | ||||
| 	url = https://github.com/hedge-dev/SWA.git | ||||
| [submodule "thirdparty/MoltenVK/MoltenVK"] | ||||
| 	path = thirdparty/MoltenVK/MoltenVK | ||||
| 	url = https://github.com/KhronosGroup/MoltenVK.git | ||||
| [submodule "thirdparty/MoltenVK/SPIRV-Cross"] | ||||
| 	path = thirdparty/MoltenVK/SPIRV-Cross | ||||
| 	url = https://github.com/KhronosGroup/SPIRV-Cross.git | ||||
| [submodule "thirdparty/plume"] | ||||
| 	path = thirdparty/plume | ||||
| 	url = https://github.com/renderbag/plume.git | ||||
|  |  | |||
|  | @ -4,7 +4,6 @@ if(NOT DEFINED ENV{VCPKG_ROOT}) | |||
|     message(FATAL_ERROR "VCPKG_ROOT is not defined!") | ||||
| endif() | ||||
| 
 | ||||
| include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake) | ||||
| set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty) | ||||
| set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools) | ||||
| set(CMAKE_CXX_STANDARD 20) | ||||
|  | @ -18,16 +17,32 @@ endif() | |||
| 
 | ||||
| set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") | ||||
| 
 | ||||
| # Target Sandy Bridge for all projects | ||||
| add_compile_options( | ||||
|     -march=sandybridge | ||||
| ) | ||||
| project("UnleashedRecomp-ALL") | ||||
| 
 | ||||
| if (APPLE) | ||||
|     enable_language(OBJC OBJCXX) | ||||
| endif() | ||||
| 
 | ||||
| if (CMAKE_OSX_ARCHITECTURES) | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES}) | ||||
| elseif(CMAKE_SYSTEM_PROCESSOR) | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) | ||||
| else() | ||||
|     set(UNLEASHED_RECOMP_ARCHITECTURE ${CMAKE_HOST_SYSTEM_PROCESSOR}) | ||||
| endif() | ||||
| string(TOLOWER "${UNLEASHED_RECOMP_ARCHITECTURE}" UNLEASHED_RECOMP_ARCHITECTURE) | ||||
| message(STATUS "Detected architecture: ${UNLEASHED_RECOMP_ARCHITECTURE}") | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_ARCHITECTURE STREQUAL "x86_64" OR UNLEASHED_RECOMP_ARCHITECTURE STREQUAL "amd64") | ||||
|     # Target Sandy Bridge for all projects | ||||
|     add_compile_options( | ||||
|         -march=sandybridge | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| add_subdirectory(${UNLEASHED_RECOMP_THIRDPARTY_ROOT}) | ||||
| add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT}) | ||||
| 
 | ||||
| project("UnleashedRecomp-ALL") | ||||
| 
 | ||||
| # Include sub-projects. | ||||
| add_subdirectory("UnleashedRecompLib") | ||||
| add_subdirectory("UnleashedRecomp") | ||||
|  |  | |||
|  | @ -113,6 +113,58 @@ | |||
|                 "CMAKE_BUILD_TYPE": "Release", | ||||
|                 "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-base", | ||||
|             "hidden": true, | ||||
|             "generator": "Ninja", | ||||
|             "binaryDir": "${sourceDir}/out/build/${presetName}", | ||||
|             "installDir": "${sourceDir}/out/install/${presetName}", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_TOOLCHAIN_FILE": { | ||||
|                     "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake", | ||||
|                     "type": "FILEPATH" | ||||
|                 }, | ||||
|                 "CMAKE_OSX_DEPLOYMENT_TARGET": "13.0" | ||||
|             }, | ||||
|             "environment": { | ||||
|                 "VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg" | ||||
|             }, | ||||
|             "condition": { | ||||
|                 "type": "equals", | ||||
|                 "lhs": "${hostSystemName}", | ||||
|                 "rhs": "Darwin" | ||||
|             }, | ||||
|             "vendor": { | ||||
|                 "microsoft.com/VisualStudioRemoteSettings/CMake/2.0": { | ||||
|                     "remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}" | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-debug", | ||||
|             "displayName": "macOS-Debug", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Debug" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-relwithdebinfo", | ||||
|             "displayName": "macOS-RelWithDebInfo", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "RelWithDebInfo" | ||||
|             } | ||||
|         }, | ||||
|         { | ||||
|             "name": "macos-release", | ||||
|             "displayName": "macOS-Release", | ||||
|             "inherits": "macos-base", | ||||
|             "cacheVariables": { | ||||
|                 "CMAKE_BUILD_TYPE": "Release", | ||||
|                 "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true | ||||
|             } | ||||
|         } | ||||
|     ] | ||||
| } | ||||
|  |  | |||
|  | @ -97,6 +97,14 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux") | |||
|         "os/linux/user_linux.cpp" | ||||
|         "os/linux/version_linux.cpp" | ||||
|     ) | ||||
| elseif (APPLE) | ||||
|     set(UNLEASHED_RECOMP_OS_CXX_SOURCES | ||||
|         "os/macos/logger_macos.cpp" | ||||
|         "os/macos/media_macos.cpp" | ||||
|         "os/macos/process_macos.cpp" | ||||
|         "os/macos/user_macos.cpp" | ||||
|         "os/macos/version_macos.cpp" | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| set(UNLEASHED_RECOMP_CPU_CXX_SOURCES | ||||
|  | @ -108,18 +116,11 @@ set(UNLEASHED_RECOMP_GPU_CXX_SOURCES | |||
|     "gpu/imgui/imgui_common.cpp" | ||||
|     "gpu/imgui/imgui_font_builder.cpp" | ||||
|     "gpu/imgui/imgui_snapshot.cpp" | ||||
|     "gpu/rhi/plume_vulkan.cpp" | ||||
| ) | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     list(APPEND UNLEASHED_RECOMP_GPU_CXX_SOURCES | ||||
|         "gpu/rhi/plume_d3d12.cpp" | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| set(UNLEASHED_RECOMP_APU_CXX_SOURCES | ||||
|     "apu/audio.cpp" | ||||
|     "apu/embedded_player.cpp" | ||||
|     "apu/embedded_player.cpp" | ||||
|     "apu/driver/sdl2_driver.cpp" | ||||
| ) | ||||
| 
 | ||||
|  | @ -149,16 +150,16 @@ set(UNLEASHED_RECOMP_PATCHES_CXX_SOURCES | |||
| 
 | ||||
| set(UNLEASHED_RECOMP_UI_CXX_SOURCES | ||||
|     "ui/achievement_menu.cpp" | ||||
|     "ui/achievement_overlay.cpp" | ||||
|     "ui/achievement_overlay.cpp" | ||||
|     "ui/black_bar.cpp" | ||||
|     "ui/button_guide.cpp" | ||||
|     "ui/fader.cpp" | ||||
|     "ui/game_window.cpp" | ||||
|     "ui/game_window.cpp" | ||||
|     "ui/imgui_utils.cpp" | ||||
|     "ui/installer_wizard.cpp" | ||||
|     "ui/message_window.cpp" | ||||
|     "ui/options_menu.cpp" | ||||
|     "ui/options_menu_thumbnails.cpp" | ||||
|     "ui/options_menu_thumbnails.cpp" | ||||
|     "ui/tv_static.cpp" | ||||
| ) | ||||
| 
 | ||||
|  | @ -180,7 +181,7 @@ set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES | |||
| set(UNLEASHED_RECOMP_USER_CXX_SOURCES | ||||
|     "user/achievement_data.cpp" | ||||
|     "user/achievement_manager.cpp" | ||||
|     "user/config.cpp" | ||||
|     "user/config.cpp" | ||||
|     "user/registry.cpp" | ||||
|     "user/paths.cpp" | ||||
|     "user/persistent_data.cpp" | ||||
|  | @ -213,25 +214,17 @@ set(UNLEASHED_RECOMP_THIRDPARTY_INCLUDES | |||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include" | ||||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb" | ||||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/unordered_dense/include" | ||||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/volk" | ||||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include" | ||||
|     "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include" | ||||
|     "${UNLEASHED_RECOMP_TOOLS_ROOT}/bc_diff" | ||||
|     "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source" | ||||
| ) | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     list(APPEND UNLEASHED_RECOMP_THIRDPARTY_INCLUDES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include") | ||||
|     list(APPEND UNLEASHED_RECOMP_THIRDPARTY_SOURCES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp") | ||||
| endif() | ||||
| 
 | ||||
| set_source_files_properties(${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) | ||||
| 
 | ||||
| set(UNLEASHED_RECOMP_CXX_SOURCES | ||||
|     "app.cpp" | ||||
|     "exports.cpp" | ||||
|     "main.cpp" | ||||
|     "misc_impl.cpp" | ||||
|     "misc_impl.cpp" | ||||
|     "preload_executable.cpp" | ||||
|     "sdl_listener.cpp" | ||||
|     "stdafx.cpp" | ||||
|  | @ -250,11 +243,11 @@ set(UNLEASHED_RECOMP_CXX_SOURCES | |||
|     ${UNLEASHED_RECOMP_USER_CXX_SOURCES} | ||||
|     ${UNLEASHED_RECOMP_MOD_CXX_SOURCES} | ||||
|     ${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} | ||||
| ) | ||||
| ) | ||||
| 
 | ||||
| include("version.cmake") | ||||
| 
 | ||||
| set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | ||||
| include("version.cmake") | ||||
| 
 | ||||
| set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt") | ||||
| 
 | ||||
| # Only show Git info and build type if not Release. | ||||
| set(SHOW_GIT_INFO_AND_BUILD_TYPE 0) | ||||
|  | @ -270,97 +263,129 @@ GenerateVersionSources( | |||
|     BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|     SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|     SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
| ) | ||||
| ) | ||||
| 
 | ||||
| if (WIN32) | ||||
|     # Create binary version number for Win32 integer attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_CSV 1 | ||||
|         OUTPUT_VAR WIN32_VERSION_BINARY | ||||
|     ) | ||||
| 
 | ||||
|     # Create string version number for Win32 detailed attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         OUTPUT_VAR WIN32_VERSION_STRING | ||||
|     ) | ||||
| 
 | ||||
|     # Create binary version number for Win32 integer attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_CSV 1 | ||||
|         OUTPUT_VAR WIN32_VERSION_BINARY | ||||
|     ) | ||||
| 
 | ||||
|     # Create string version number for Win32 detailed attributes. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         BUILD_TYPE ${CMAKE_BUILD_TYPE} | ||||
|         SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE} | ||||
|         OUTPUT_VAR WIN32_VERSION_STRING | ||||
|     ) | ||||
| 
 | ||||
|     # Set Win32 icon path. | ||||
|     set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") | ||||
|     set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico") | ||||
| 
 | ||||
|     configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY) | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") | ||||
| 
 | ||||
|     # Hide console for release configurations. | ||||
|     if (${CMAKE_BUILD_TYPE} MATCHES "Release") | ||||
|         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc") | ||||
| 
 | ||||
|     # Hide console for release configurations. | ||||
|     if (${CMAKE_BUILD_TYPE} MATCHES "Release") | ||||
|         target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup") | ||||
|     endif() | ||||
| elseif (APPLE) | ||||
|     # Create version number for app bundle. | ||||
|     CreateVersionString( | ||||
|         VERSION_TXT ${VERSION_TXT} | ||||
|         OUTPUT_VAR MACOS_BUNDLE_VERSION | ||||
|     ) | ||||
| 
 | ||||
|     add_executable(UnleashedRecomp MACOSX_BUNDLE | ||||
|         ${UNLEASHED_RECOMP_CXX_SOURCES} | ||||
|         res/macos/game_icon.icns | ||||
|     ) | ||||
|     set_source_files_properties(res/macos/game_icon.icns PROPERTIES | ||||
|         MACOSX_PACKAGE_LOCATION Resources) | ||||
|     set_target_properties(UnleashedRecomp PROPERTIES | ||||
|         OUTPUT_NAME "Unleashed Recompiled" | ||||
|         MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/res/macos/MacOSXBundleInfo.plist.in | ||||
|         MACOSX_BUNDLE_GUI_IDENTIFIER hedge-dev.UnleashedRecomp | ||||
|         MACOSX_BUNDLE_BUNDLE_NAME "Unleashed Recompiled" | ||||
|         MACOSX_BUNDLE_BUNDLE_VERSION ${MACOS_BUNDLE_VERSION} | ||||
|         MACOSX_BUNDLE_SHORT_VERSION_STRING ${MACOS_BUNDLE_VERSION} | ||||
|         MACOSX_BUNDLE_ICON_FILE "game_icon.icns" | ||||
|     ) | ||||
| 
 | ||||
|     # Linking with MoltenVK directly would prevent using the system Vulkan loader to load with debug layers. | ||||
|     # Instead, copy the MoltenVK dylib to the app bundle along with an ICD file for the loader to find it. | ||||
|     # In the event the loader is not installed, the MoltenVK dylib can still be picked up directly in the app bundle. | ||||
|     set(MVK_BUNDLED_PATH "Resources/vulkan/icd.d") | ||||
|     set(MVK_DST "${CMAKE_CURRENT_BINARY_DIR}/Unleashed Recompiled.app/Contents/${MVK_BUNDLED_PATH}") | ||||
|     set_property(TARGET UnleashedRecomp APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLED_PATH}") | ||||
| 
 | ||||
|     set(MVK_ICD_SRC "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK/MoltenVK/MoltenVK/icd/MoltenVK_icd.json") | ||||
|     set(MVK_ICD_DST "${MVK_DST}/MoltenVK_icd.json") | ||||
|     set(MVK_DYLIB_SRC "${CMAKE_BINARY_DIR}/thirdparty/MoltenVK/libMoltenVK.dylib") | ||||
|     set(MVK_DYLIB_DST "${MVK_DST}/libMoltenVK.dylib") | ||||
| 
 | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DST}) | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_ICD_DST} | ||||
|         DEPENDS ${MVK_ICD_SRC} ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy ${MVK_ICD_SRC} ${MVK_ICD_DST}) | ||||
|     add_custom_command( | ||||
|         OUTPUT ${MVK_DYLIB_DST} | ||||
|         DEPENDS ${MVK_DYLIB_SRC} ${MVK_DST} | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST}) | ||||
|     add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST}) | ||||
|     add_dependencies(CopyMoltenVK MoltenVK) | ||||
|     add_dependencies(UnleashedRecomp CopyMoltenVK) | ||||
| else() | ||||
|     add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES}) | ||||
| endif() | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_FLATPAK) | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         "UNLEASHED_RECOMP_FLATPAK" | ||||
|         "GAME_INSTALL_DIRECTORY=\"/var/data\"" | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         "UNLEASHED_RECOMP_FLATPAK" | ||||
|         "GAME_INSTALL_DIRECTORY=\"/var/data\"" | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| find_package(CURL REQUIRED) | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     find_package(directx-headers CONFIG REQUIRED) | ||||
|     find_package(directx12-agility CONFIG REQUIRED) | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE  | ||||
|         UNLEASHED_RECOMP_D3D12 | ||||
|         D3D12MA_USING_DIRECTX_HEADERS | ||||
|         D3D12MA_OPTIONS16_SUPPORTED | ||||
|     ) | ||||
| endif() | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE UNLEASHED_RECOMP_D3D12) | ||||
| 
 | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "Linux") | ||||
|     target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED) | ||||
| endif() | ||||
| 
 | ||||
| find_package(directx-dxc REQUIRED) | ||||
| find_package(CURL REQUIRED) | ||||
| 
 | ||||
| if (UNLEASHED_RECOMP_D3D12) | ||||
|     file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) | ||||
|     add_custom_command(TARGET UnleashedRecomp POST_BUILD | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 | ||||
|        COMMAND_EXPAND_LISTS | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12 | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectXShaderCompiler,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp> | ||||
|         COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DXIL,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp> | ||||
|         COMMAND_EXPAND_LISTS | ||||
|     ) | ||||
|      | ||||
|     find_file(DIRECTX_DXIL_LIBRARY "dxil.dll") | ||||
|     file(COPY ${DIRECTX_DXIL_LIBRARY} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) | ||||
| 
 | ||||
|     target_link_libraries(UnleashedRecomp PRIVATE | ||||
|         Microsoft::DirectX-Headers  | ||||
|         Microsoft::DirectX-Guids  | ||||
|         Microsoft::DirectX12-Agility | ||||
|         Microsoft::DirectXShaderCompiler | ||||
|         Microsoft::DXIL | ||||
|         dxgi | ||||
|     ) | ||||
| endif() | ||||
| 
 | ||||
| file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE) | ||||
| 
 | ||||
| if (WIN32) | ||||
|     target_link_libraries(UnleashedRecomp PRIVATE | ||||
|         comctl32 | ||||
|         comctl32 | ||||
|         dwmapi | ||||
|         ntdll | ||||
|         ntdll | ||||
|         Shcore | ||||
|         Synchronization | ||||
|         winmm | ||||
|         winmm | ||||
|         windowsapp | ||||
|     ) | ||||
| endif() | ||||
| endif() | ||||
| 
 | ||||
| target_link_libraries(UnleashedRecomp PRIVATE | ||||
|     fmt::fmt | ||||
|  | @ -375,6 +400,7 @@ target_link_libraries(UnleashedRecomp PRIVATE | |||
|     UnleashedRecompLib | ||||
|     xxHash::xxhash | ||||
|     CURL::libcurl | ||||
|     plume | ||||
| ) | ||||
| 
 | ||||
| target_include_directories(UnleashedRecomp PRIVATE | ||||
|  | @ -411,16 +437,16 @@ function(compile_shader FILE_PATH TARGET_NAME) | |||
| endfunction() | ||||
| 
 | ||||
| function(compile_vertex_shader FILE_PATH) | ||||
|     compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y) | ||||
|     compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y -DUNLEASHED_RECOMP) | ||||
| endfunction() | ||||
| 
 | ||||
| function(compile_pixel_shader FILE_PATH) | ||||
|     compile_shader(${FILE_PATH} ps_6_0) | ||||
|     compile_shader(${FILE_PATH} ps_6_0 -DUNLEASHED_RECOMP) | ||||
| endfunction() | ||||
| 
 | ||||
| compile_pixel_shader(blend_color_alpha_ps) | ||||
| compile_vertex_shader(copy_vs) | ||||
| compile_pixel_shader(copy_color_ps) | ||||
| compile_pixel_shader(blend_color_alpha_ps) | ||||
| compile_vertex_shader(copy_vs) | ||||
| compile_pixel_shader(copy_color_ps) | ||||
| compile_pixel_shader(copy_depth_ps) | ||||
| compile_pixel_shader(csd_filter_ps) | ||||
| compile_vertex_shader(csd_no_tex_vs) | ||||
|  | @ -434,7 +460,7 @@ compile_pixel_shader(gamma_correction_ps) | |||
| compile_pixel_shader(imgui_ps) | ||||
| compile_vertex_shader(imgui_vs) | ||||
| compile_pixel_shader(movie_ps) | ||||
| compile_vertex_shader(movie_vs) | ||||
| compile_vertex_shader(movie_vs) | ||||
| compile_pixel_shader(resolve_msaa_color_2x) | ||||
| compile_pixel_shader(resolve_msaa_color_4x) | ||||
| compile_pixel_shader(resolve_msaa_color_8x) | ||||
|  | @ -444,7 +470,7 @@ compile_pixel_shader(resolve_msaa_depth_8x) | |||
| 
 | ||||
| set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") | ||||
| set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") | ||||
| 
 | ||||
| 
 | ||||
| ## Miscellaneous ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd") | ||||
|  | @ -456,7 +482,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/co | |||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select.dds" ARRAY_NAME "g_select" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/light.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/light.dds" ARRAY_NAME "g_light" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| 
 | ||||
| ## Installer ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd") | ||||
|  | @ -468,23 +494,23 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in | |||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_NAME "g_install_007" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_NAME "g_install_008" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_NAME "g_miles_electric_icon" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| ## Options Menu ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_ps.dds" ARRAY_NAME "g_allow_background_input_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" ARRAY_NAME "g_allow_background_input_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" ARRAY_NAME "g_antialiasing_8x" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" ARRAY_NAME "g_control_tutorial_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/controller_icons.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/controller_icons.dds" ARRAY_NAME "g_controller_icons" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/default.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/default.dds" ARRAY_NAME "g_default" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/effects_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/effects_volume.dds" ARRAY_NAME "g_effects_volume" COMPRESSION_TYPE "zstd") | ||||
|  | @ -500,7 +526,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op | |||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" ARRAY_NAME "g_motion_blur_off" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" ARRAY_NAME "g_motion_blur_original" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" ARRAY_NAME "g_motion_blur_enhanced" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" ARRAY_NAME "g_movie_scale_fill" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_attenuation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_attenuation.dds" ARRAY_NAME "g_music_attenuation" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_volume.dds" ARRAY_NAME "g_music_volume" COMPRESSION_TYPE "zstd") | ||||
|  | @ -509,34 +535,34 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op | |||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" ARRAY_NAME "g_shadow_resolution_x2048" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" ARRAY_NAME "g_shadow_resolution_x4096" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" ARRAY_NAME "g_shadow_resolution_x8192" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_xb.dds" ARRAY_NAME "g_time_of_day_transition_xbox" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" ARRAY_NAME "g_transparency_antialiasing_false" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" ARRAY_NAME "g_transparency_antialiasing_true" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" ARRAY_NAME "g_ui_alignment_edge" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vertical_camera.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vertical_camera.dds" ARRAY_NAME "g_vertical_camera" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/voice_language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/voice_language.dds" ARRAY_NAME "g_voice_language" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_ps.dds" ARRAY_NAME "g_vibration_ps" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_off.dds" ARRAY_NAME "g_vsync_off" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" ARRAY_NAME "g_xbox_color_correction" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static_flash.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static_flash.dds" ARRAY_NAME "g_options_static_flash" COMPRESSION_TYPE "zstd") | ||||
| 
 | ||||
| 
 | ||||
| ## Game Icon ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") | ||||
| 
 | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night") | ||||
| 
 | ||||
| ## Audio ## | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_cursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_cursor.ogg" ARRAY_NAME "g_sys_worldmap_cursor") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_finaldecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_finaldecide.ogg" ARRAY_NAME "g_sys_worldmap_finaldecide") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecansel.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecansel.ogg" ARRAY_NAME "g_sys_actstg_pausecansel") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecursor.ogg" ARRAY_NAME "g_sys_actstg_pausecursor") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausedecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausedecide.ogg" ARRAY_NAME "g_sys_actstg_pausedecide") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinclose.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinclose.ogg" ARRAY_NAME "g_sys_actstg_pausewinclose") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen") | ||||
| BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen") | ||||
|  |  | |||
|  | @ -40,29 +40,101 @@ GuestThreadContext::~GuestThreadContext() | |||
|     g_userHeap.Free(thread); | ||||
| } | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
| static size_t GetStackSize() | ||||
| { | ||||
|     // Cache as this should not change.
 | ||||
|     static size_t stackSize = 0; | ||||
|     if (stackSize == 0) | ||||
|     { | ||||
|         // 8 MiB is a typical default.
 | ||||
|         constexpr auto defaultSize = 8 * 1024 * 1024; | ||||
|         struct rlimit lim; | ||||
|         const auto ret = getrlimit(RLIMIT_STACK, &lim); | ||||
|         if (ret == 0 && lim.rlim_cur < defaultSize) | ||||
|         { | ||||
|             // Use what the system allows.
 | ||||
|             stackSize = lim.rlim_cur; | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             stackSize = defaultSize; | ||||
|         } | ||||
|     } | ||||
|     return stackSize; | ||||
| } | ||||
| 
 | ||||
| static void* GuestThreadFunc(void* arg) | ||||
| { | ||||
|     GuestThreadHandle* hThread = (GuestThreadHandle*)arg; | ||||
| #else | ||||
| static void GuestThreadFunc(GuestThreadHandle* hThread) | ||||
| { | ||||
| #endif | ||||
|     hThread->suspended.wait(true); | ||||
|     GuestThread::Start(hThread->params); | ||||
| #ifdef USE_PTHREAD | ||||
|     return nullptr; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params) | ||||
|     : params(params), suspended((params.flags & 0x1) != 0), thread(GuestThreadFunc, this) | ||||
|     : params(params), suspended((params.flags & 0x1) != 0) | ||||
| #ifdef USE_PTHREAD | ||||
| { | ||||
|     pthread_attr_t attr; | ||||
|     pthread_attr_init(&attr); | ||||
|     pthread_attr_setstacksize(&attr, GetStackSize()); | ||||
|     const auto ret = pthread_create(&thread, &attr, GuestThreadFunc, this); | ||||
|     if (ret != 0) { | ||||
|         fprintf(stderr, "pthread_create failed with error code 0x%X.\n", ret); | ||||
|         return; | ||||
|     } | ||||
| } | ||||
| #else | ||||
|       , thread(GuestThreadFunc, this) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| GuestThreadHandle::~GuestThreadHandle() | ||||
| { | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_join(thread, nullptr); | ||||
| #else | ||||
|     if (thread.joinable()) | ||||
|         thread.join(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| template <typename ThreadType> | ||||
| static uint32_t CalcThreadId(const ThreadType& id) | ||||
| { | ||||
|     if constexpr (sizeof(id) == 4) | ||||
|         return *reinterpret_cast<const uint32_t*>(&id); | ||||
|     else | ||||
|         return XXH32(&id, sizeof(id), 0); | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThreadHandle::GetThreadId() const | ||||
| { | ||||
| #ifdef USE_PTHREAD | ||||
|     return CalcThreadId(thread); | ||||
| #else | ||||
|     return CalcThreadId(thread.get_id()); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThreadHandle::Wait(uint32_t timeout) | ||||
| { | ||||
|     assert(timeout == INFINITE); | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_join(thread, nullptr); | ||||
| #else | ||||
|     if (thread.joinable()) | ||||
|         thread.join(); | ||||
| #endif | ||||
| 
 | ||||
|     return STATUS_WAIT_0; | ||||
| } | ||||
|  | @ -80,27 +152,25 @@ uint32_t GuestThread::Start(const GuestThreadParams& params) | |||
|     return ctx.ppcContext.r3.u32; | ||||
| } | ||||
| 
 | ||||
| static uint32_t GetThreadId(const std::thread::id& id) | ||||
| { | ||||
|     if constexpr (sizeof(id) == 4) | ||||
|         return *reinterpret_cast<const uint32_t*>(&id); | ||||
|     else | ||||
|         return XXH32(&id, sizeof(id), 0); | ||||
| } | ||||
| 
 | ||||
| GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId) | ||||
| { | ||||
|     auto hThread = CreateKernelObject<GuestThreadHandle>(params); | ||||
| 
 | ||||
|     if (threadId != nullptr) | ||||
|         *threadId = GetThreadId(hThread->thread.get_id()); | ||||
|     { | ||||
|         *threadId = hThread->GetThreadId(); | ||||
|     } | ||||
| 
 | ||||
|     return hThread; | ||||
| } | ||||
| 
 | ||||
| uint32_t GuestThread::GetCurrentThreadId() | ||||
| { | ||||
|     return GetThreadId(std::this_thread::get_id()); | ||||
| #ifdef USE_PTHREAD | ||||
|     return CalcThreadId(pthread_self()); | ||||
| #else | ||||
|     return CalcThreadId(std::this_thread::get_id()); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void GuestThread::SetLastError(uint32_t error) | ||||
|  |  | |||
|  | @ -2,6 +2,15 @@ | |||
| 
 | ||||
| #include <kernel/xdm.h> | ||||
| 
 | ||||
| // Use pthreads directly on macOS to be able to increase default stack size.
 | ||||
| #ifdef __APPLE__ | ||||
| #define USE_PTHREAD 1 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef USE_PTHREAD | ||||
| #include <pthread.h> | ||||
| #endif | ||||
| 
 | ||||
| #define CURRENT_THREAD_HANDLE uint32_t(-2) | ||||
| 
 | ||||
| struct GuestThreadContext | ||||
|  | @ -24,11 +33,17 @@ struct GuestThreadHandle : KernelObject | |||
| { | ||||
|     GuestThreadParams params; | ||||
|     std::atomic<bool> suspended; | ||||
| #ifdef USE_PTHREAD | ||||
|     pthread_t thread; | ||||
| #else | ||||
|     std::thread thread; | ||||
| #endif | ||||
| 
 | ||||
|     GuestThreadHandle(const GuestThreadParams& params); | ||||
|     ~GuestThreadHandle() override; | ||||
| 
 | ||||
|     uint32_t GetThreadId() const; | ||||
| 
 | ||||
|     uint32_t Wait(uint32_t timeout) override; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,21 +0,0 @@ | |||
| MIT License | ||||
| 
 | ||||
| Copyright (c) 2024 renderbag and contributors | ||||
| 
 | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
| 
 | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,481 +0,0 @@ | |||
| //
 | ||||
| // plume
 | ||||
| //
 | ||||
| // Copyright (c) 2024 renderbag and contributors. All rights reserved.
 | ||||
| // Licensed under the MIT license. See LICENSE file for details.
 | ||||
| //
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "plume_render_interface.h" | ||||
| 
 | ||||
| #include <map> | ||||
| #include <mutex> | ||||
| #include <unordered_map> | ||||
| 
 | ||||
| #include <directx/d3d12.h> | ||||
| #include <dxgi1_4.h> | ||||
| 
 | ||||
| #include "D3D12MemAlloc.h" | ||||
| 
 | ||||
| namespace plume { | ||||
|     struct D3D12Buffer; | ||||
|     struct D3D12CommandQueue; | ||||
|     struct D3D12Device; | ||||
|     struct D3D12GraphicsPipeline; | ||||
|     struct D3D12Interface; | ||||
|     struct D3D12Pipeline; | ||||
|     struct D3D12Pool; | ||||
|     struct D3D12PipelineLayout; | ||||
|     struct D3D12Texture; | ||||
| 
 | ||||
|     struct D3D12DescriptorHeapAllocator { | ||||
|         enum : uint32_t { | ||||
|             INVALID_OFFSET = 0xFFFFFFFFU | ||||
|         }; | ||||
| 
 | ||||
|         // Reference implementation http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
 | ||||
|         struct FreeBlock; | ||||
| 
 | ||||
|         typedef std::map<uint32_t, FreeBlock> OffsetFreeBlockMap; | ||||
|         typedef std::multimap<uint32_t, OffsetFreeBlockMap::iterator> SizeFreeBlockMap; | ||||
| 
 | ||||
|         struct FreeBlock { | ||||
|             uint32_t size; | ||||
|             SizeFreeBlockMap::iterator sizeMapIterator; | ||||
| 
 | ||||
|             FreeBlock(uint32_t size) { | ||||
|                 this->size = size; | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         ID3D12DescriptorHeap *heap = nullptr; | ||||
|         uint32_t heapSize = 0; | ||||
|         uint32_t freeSize = 0; | ||||
|         D3D12Device *device = nullptr; | ||||
|         D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle = {}; | ||||
|         D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle = {}; | ||||
|         UINT descriptorHandleIncrement = 0; | ||||
|         OffsetFreeBlockMap offsetFreeBlockMap; | ||||
|         SizeFreeBlockMap sizeFreeBlockMap; | ||||
|         std::mutex allocationMutex; | ||||
| 
 | ||||
|         D3D12DescriptorHeapAllocator(D3D12Device *device, uint32_t heapSize, D3D12_DESCRIPTOR_HEAP_TYPE heapType); | ||||
|         ~D3D12DescriptorHeapAllocator(); | ||||
|         void addFreeBlock(uint32_t offset, uint32_t size); | ||||
|         uint32_t allocate(uint32_t size); | ||||
|         void free(uint32_t offset, uint32_t size); | ||||
|         D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleAt(uint32_t index) const; | ||||
|         D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandleAt(uint32_t index) const; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12DescriptorSet : RenderDescriptorSet { | ||||
|         D3D12Device *device = nullptr; | ||||
| 
 | ||||
|         struct HeapAllocation { | ||||
|             uint32_t offset = 0; | ||||
|             uint32_t count = 0; | ||||
|         }; | ||||
| 
 | ||||
|         HeapAllocation viewAllocation; | ||||
|         HeapAllocation samplerAllocation; | ||||
|         std::vector<RenderDescriptorRangeType> descriptorTypes; | ||||
|         std::vector<uint32_t> descriptorHeapIndices; | ||||
|         uint32_t descriptorTypeMaxIndex = 0; | ||||
| 
 | ||||
|         D3D12DescriptorSet(D3D12Device *device, const RenderDescriptorSetDesc &desc); | ||||
|         ~D3D12DescriptorSet() override; | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override; | ||||
|         void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override; | ||||
|         void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override; | ||||
|         void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override; | ||||
|         void setSRV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *viewDesc); | ||||
|         void setUAV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *viewDesc); | ||||
|         void setCBV(uint32_t descriptorIndex, ID3D12Resource *resource, uint64_t bufferSize); | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12SwapChain : RenderSwapChain { | ||||
|         IDXGISwapChain3 *d3d = nullptr; | ||||
|         HANDLE waitableObject = 0; | ||||
|         D3D12CommandQueue *commandQueue = nullptr; | ||||
|         RenderWindow renderWindow = {}; | ||||
|         std::vector<D3D12Texture> textures; | ||||
|         uint32_t textureCount = 0; | ||||
|         RenderFormat format = RenderFormat::UNKNOWN; | ||||
|         DXGI_FORMAT nativeFormat = DXGI_FORMAT_UNKNOWN; | ||||
|         uint32_t width = 0; | ||||
|         uint32_t height = 0; | ||||
|         uint32_t refreshRate = 0; | ||||
|         bool vsyncEnabled = true; | ||||
|         uint32_t maxFrameLatency = 0; | ||||
| 
 | ||||
|         D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency); | ||||
|         ~D3D12SwapChain() override; | ||||
|         bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override; | ||||
|         void wait() override; | ||||
|         bool resize() override; | ||||
|         bool needsResize() const override; | ||||
|         void setVsyncEnabled(bool vsyncEnabled) override; | ||||
|         bool isVsyncEnabled() const override; | ||||
|         uint32_t getWidth() const override; | ||||
|         uint32_t getHeight() const override; | ||||
|         RenderTexture *getTexture(uint32_t textureIndex) override; | ||||
|         uint32_t getTextureCount() const override; | ||||
|         bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override; | ||||
|         RenderWindow getWindow() const override; | ||||
|         bool isEmpty() const override; | ||||
|         uint32_t getRefreshRate() const override; | ||||
|         void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const; | ||||
|         void setTextures(); | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Framebuffer : RenderFramebuffer { | ||||
|         D3D12Device *device = nullptr; | ||||
|         uint32_t width = 0; | ||||
|         uint32_t height = 0; | ||||
|         std::vector<const D3D12Texture *> colorTargets; | ||||
|         const D3D12Texture *depthTarget = nullptr; | ||||
|         std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> colorHandles; | ||||
|         D3D12_CPU_DESCRIPTOR_HANDLE depthHandle = {}; | ||||
| 
 | ||||
|         D3D12Framebuffer(D3D12Device *device, const RenderFramebufferDesc &desc); | ||||
|         ~D3D12Framebuffer() override; | ||||
|         uint32_t getWidth() const override; | ||||
|         uint32_t getHeight() const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12QueryPool : RenderQueryPool { | ||||
|         D3D12Device *device = nullptr; | ||||
|         ID3D12QueryHeap *d3d = nullptr; | ||||
|         std::vector<uint64_t> results; | ||||
|         std::unique_ptr<RenderBuffer> readbackBuffer; | ||||
| 
 | ||||
|         D3D12QueryPool(D3D12Device *device, uint32_t queryCount); | ||||
|         virtual ~D3D12QueryPool() override; | ||||
|         virtual void queryResults() override; | ||||
|         virtual const uint64_t *getResults() const override; | ||||
|         virtual uint32_t getCount() const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12CommandList : RenderCommandList { | ||||
|         ID3D12GraphicsCommandList9 *d3d = nullptr; | ||||
|         ID3D12CommandAllocator *commandAllocator = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         RenderCommandListType type = RenderCommandListType::UNKNOWN; | ||||
|         const D3D12Framebuffer *targetFramebuffer = nullptr; | ||||
|         bool targetFramebufferSamplePositionsSet = false; | ||||
|         bool open = false; | ||||
|         const D3D12PipelineLayout *activeComputePipelineLayout = nullptr; | ||||
|         const D3D12PipelineLayout *activeGraphicsPipelineLayout = nullptr; | ||||
|         const D3D12GraphicsPipeline *activeGraphicsPipeline = nullptr; | ||||
|         bool descriptorHeapsSet = false; | ||||
|         D3D12_PRIMITIVE_TOPOLOGY activeTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; | ||||
|         bool activeSamplePositions = false; | ||||
| 
 | ||||
|         D3D12CommandList(D3D12Device *device, RenderCommandListType type); | ||||
|         ~D3D12CommandList() override; | ||||
|         void begin() override; | ||||
|         void end() override; | ||||
|         void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override; | ||||
|         void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override; | ||||
|         void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override; | ||||
|         void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override; | ||||
|         void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override; | ||||
|         void setPipeline(const RenderPipeline *pipeline) override; | ||||
|         void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override; | ||||
|         void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setIndexBuffer(const RenderIndexBufferView *view) override; | ||||
|         void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override; | ||||
|         void setViewports(const RenderViewport *viewports, uint32_t count) override; | ||||
|         void setScissors(const RenderRect *scissorRects, uint32_t count) override; | ||||
|         void setFramebuffer(const RenderFramebuffer *framebuffer) override; | ||||
|         void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override; | ||||
|         void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override; | ||||
|         void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override; | ||||
|         void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override; | ||||
|         void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override; | ||||
|         void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override; | ||||
|         void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override; | ||||
|         void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override; | ||||
|         void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override; | ||||
|         void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override; | ||||
|         void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override; | ||||
|         void discardTexture(const RenderTexture* texture) override; | ||||
|         void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override; | ||||
|         void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override; | ||||
|         void checkDescriptorHeaps(); | ||||
|         void notifyDescriptorHeapWasChangedExternally(); | ||||
|         void checkTopology(); | ||||
|         void checkFramebufferSamplePositions(); | ||||
|         void setSamplePositions(const RenderTexture *texture); | ||||
|         void resetSamplePositions(); | ||||
|         void setDescriptorSet(const D3D12PipelineLayout *activePipelineLayout, RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute); | ||||
|         void setRootDescriptorTable(D3D12DescriptorHeapAllocator *heapAllocator, D3D12DescriptorSet::HeapAllocation &heapAllocation, uint32_t rootIndex, bool setCompute); | ||||
|         void setRootDescriptor(const D3D12PipelineLayout *activePipelineLayout, RenderBufferReference bufferReference, uint32_t setIndex, bool setCompute); | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12CommandFence : RenderCommandFence { | ||||
|         ID3D12Fence *d3d = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         HANDLE fenceEvent = 0; | ||||
|         UINT64 fenceValue = 0; | ||||
| 
 | ||||
|         D3D12CommandFence(D3D12Device *device); | ||||
|         ~D3D12CommandFence() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12CommandSemaphore : RenderCommandSemaphore { | ||||
|         ID3D12Fence *d3d = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         UINT64 semaphoreValue = 0; | ||||
| 
 | ||||
|         D3D12CommandSemaphore(D3D12Device *device); | ||||
|         ~D3D12CommandSemaphore() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12CommandQueue : RenderCommandQueue { | ||||
|         ID3D12CommandQueue *d3d = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         RenderCommandListType type = RenderCommandListType::UNKNOWN; | ||||
| 
 | ||||
|         D3D12CommandQueue(D3D12Device *device, RenderCommandListType type); | ||||
|         ~D3D12CommandQueue() override; | ||||
|         std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t newFrameLatency) override; | ||||
|         void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override; | ||||
|         void waitForCommandFence(RenderCommandFence *fence) override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Buffer : RenderBuffer { | ||||
|         ID3D12Resource *d3d = nullptr; | ||||
|         D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON; | ||||
|         D3D12Device *device = nullptr; | ||||
|         D3D12MA::Allocation *allocation = nullptr; | ||||
|         D3D12Pool *pool = nullptr; | ||||
|         RenderBufferDesc desc; | ||||
| 
 | ||||
|         D3D12Buffer() = default; | ||||
|         D3D12Buffer(D3D12Device *device, D3D12Pool *pool, const RenderBufferDesc &desc); | ||||
|         ~D3D12Buffer() override; | ||||
|         void *map(uint32_t subresource, const RenderRange *readRange) override; | ||||
|         void unmap(uint32_t subresource, const RenderRange *writtenRange) override; | ||||
|         std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override; | ||||
|         void setName(const std::string &name) override; | ||||
|         uint64_t getDeviceAddress() const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12BufferFormattedView : RenderBufferFormattedView { | ||||
|         RenderFormat format = RenderFormat::UNKNOWN; | ||||
|         D3D12Buffer *buffer = nullptr; | ||||
| 
 | ||||
|         D3D12BufferFormattedView(D3D12Buffer *buffer, RenderFormat format); | ||||
|         ~D3D12BufferFormattedView() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Texture : RenderTexture { | ||||
|         ID3D12Resource *d3d = nullptr; | ||||
|         D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON; | ||||
|         RenderTextureLayout layout = RenderTextureLayout::UNKNOWN; | ||||
|         D3D12Device *device = nullptr; | ||||
|         D3D12MA::Allocation *allocation = nullptr; | ||||
|         D3D12Pool *pool = nullptr; | ||||
|         RenderTextureDesc desc; | ||||
|         uint32_t targetAllocatorOffset = 0; | ||||
|         uint32_t targetEntryCount = 0; | ||||
|         bool targetHeapDepth = false; | ||||
| 
 | ||||
|         D3D12Texture() = default; | ||||
|         D3D12Texture(D3D12Device *device, D3D12Pool *pool, const RenderTextureDesc &desc); | ||||
|         ~D3D12Texture() override; | ||||
|         std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override; | ||||
|         void setName(const std::string &name) override; | ||||
|         void createRenderTargetHeap(); | ||||
|         void createDepthStencilHeap(); | ||||
|         void releaseTargetHeap(); | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12TextureView : RenderTextureView { | ||||
|         DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN; | ||||
|         D3D12Texture *texture = nullptr; | ||||
|         RenderTextureViewDimension dimension = RenderTextureViewDimension::UNKNOWN; | ||||
|         uint32_t mipLevels = 0; | ||||
|         uint32_t mipSlice = 0; | ||||
|         uint32_t shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; | ||||
| 
 | ||||
|         D3D12TextureView(D3D12Texture *texture, const RenderTextureViewDesc &desc); | ||||
|         ~D3D12TextureView() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12AccelerationStructure :RenderAccelerationStructure { | ||||
|         D3D12Device *device = nullptr; | ||||
|         const D3D12Buffer *buffer = nullptr; | ||||
|         uint64_t offset = 0; | ||||
|         uint64_t size = 0; | ||||
|         RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN; | ||||
| 
 | ||||
|         D3D12AccelerationStructure(D3D12Device *device, const RenderAccelerationStructureDesc &desc); | ||||
|         ~D3D12AccelerationStructure() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Pool : RenderPool { | ||||
|         D3D12MA::Pool *d3d = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         RenderPoolDesc desc; | ||||
| 
 | ||||
|         D3D12Pool(D3D12Device *device, const RenderPoolDesc &desc, bool gpuUploadHeapFallback); | ||||
|         ~D3D12Pool() override; | ||||
|         std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Shader : RenderShader { | ||||
|         const void* data = nullptr; | ||||
|         uint64_t size = 0; | ||||
|         std::string entryPointName; | ||||
|         D3D12Device *device = nullptr; | ||||
|         RenderShaderFormat format = RenderShaderFormat::UNKNOWN; | ||||
| 
 | ||||
|         D3D12Shader(D3D12Device *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format); | ||||
|         ~D3D12Shader() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Sampler : RenderSampler { | ||||
|         D3D12_SAMPLER_DESC samplerDesc = {}; | ||||
|         D3D12Device *device = nullptr; | ||||
|         RenderBorderColor borderColor = RenderBorderColor::UNKNOWN; | ||||
|         RenderShaderVisibility shaderVisibility = RenderShaderVisibility::UNKNOWN; | ||||
| 
 | ||||
|         D3D12Sampler(D3D12Device *device, const RenderSamplerDesc &desc); | ||||
|         ~D3D12Sampler() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Pipeline : RenderPipeline { | ||||
|         enum class Type { | ||||
|             Unknown, | ||||
|             Compute, | ||||
|             Graphics, | ||||
|             Raytracing | ||||
|         }; | ||||
| 
 | ||||
|         D3D12Device *device = nullptr; | ||||
|         Type type = Type::Unknown; | ||||
| 
 | ||||
|         D3D12Pipeline(D3D12Device *device, Type type); | ||||
|         virtual ~D3D12Pipeline() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12ComputePipeline : D3D12Pipeline { | ||||
|         ID3D12PipelineState *d3d = nullptr; | ||||
| 
 | ||||
|         D3D12ComputePipeline(D3D12Device *device, const RenderComputePipelineDesc &desc); | ||||
|         ~D3D12ComputePipeline() override; | ||||
|         virtual void setName(const std::string& name) const override; | ||||
|         virtual RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12GraphicsPipeline : D3D12Pipeline { | ||||
|         ID3D12PipelineState *d3d = nullptr; | ||||
|         std::vector<RenderInputSlot> inputSlots; | ||||
|         D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; | ||||
| 
 | ||||
|         D3D12GraphicsPipeline(D3D12Device *device, const RenderGraphicsPipelineDesc &desc); | ||||
|         ~D3D12GraphicsPipeline() override; | ||||
|         virtual void setName(const std::string& name) const override; | ||||
|         virtual RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12RaytracingPipeline : D3D12Pipeline { | ||||
|         ID3D12StateObject *stateObject = nullptr; | ||||
|         ID3D12StateObjectProperties *stateObjectProperties = nullptr; | ||||
|         std::vector<void *> programShaderIdentifiers; | ||||
|         std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap; | ||||
|         const D3D12PipelineLayout *pipelineLayout = nullptr; | ||||
| 
 | ||||
|         D3D12RaytracingPipeline(D3D12Device *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline); | ||||
|         ~D3D12RaytracingPipeline() override; | ||||
|         virtual void setName(const std::string& name) const override; | ||||
|         virtual RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12PipelineLayout : RenderPipelineLayout { | ||||
|         ID3D12RootSignature *rootSignature = nullptr; | ||||
|         D3D12Device *device = nullptr; | ||||
|         std::vector<RenderPushConstantRange> pushConstantRanges; | ||||
|         std::vector<uint32_t> setViewRootIndices; | ||||
|         std::vector<uint32_t> setSamplerRootIndices; | ||||
|         std::vector<std::pair<uint32_t, RenderRootDescriptorType>> rootDescriptorRootIndicesAndTypes; | ||||
|         uint32_t setCount = 0; | ||||
|         uint32_t rootCount = 0; | ||||
| 
 | ||||
|         D3D12PipelineLayout(D3D12Device *device, const RenderPipelineLayoutDesc &desc); | ||||
|         ~D3D12PipelineLayout() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Device : RenderDevice { | ||||
|         ID3D12Device8 *d3d = nullptr; | ||||
|         D3D12Interface *renderInterface = nullptr; | ||||
|         IDXGIAdapter1 *adapter = nullptr; | ||||
|         D3D12MA::Allocator *allocator = nullptr; | ||||
|         D3D_SHADER_MODEL shaderModel = D3D_SHADER_MODEL(0); | ||||
|         std::unique_ptr<RenderPipelineLayout> rtDummyGlobalPipelineLayout; | ||||
|         std::unique_ptr<RenderPipelineLayout> rtDummyLocalPipelineLayout; | ||||
|         std::unique_ptr<D3D12DescriptorHeapAllocator> viewHeapAllocator; | ||||
|         std::unique_ptr<D3D12DescriptorHeapAllocator> samplerHeapAllocator; | ||||
|         std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator; | ||||
|         std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator; | ||||
|         std::unique_ptr<D3D12Pool> customUploadPool; | ||||
|         RenderDeviceCapabilities capabilities; | ||||
|         RenderDeviceDescription description; | ||||
|         uint64_t timestampFrequency = 1; | ||||
|         bool gpuUploadHeapFallback = false; | ||||
| 
 | ||||
|         D3D12Device(D3D12Interface *renderInterface, const std::string &preferredDeviceName); | ||||
|         ~D3D12Device() override; | ||||
|         std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override; | ||||
|         std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override; | ||||
|         std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override; | ||||
|         std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override; | ||||
|         std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override; | ||||
|         std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override; | ||||
|         std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override; | ||||
|         std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override; | ||||
|         std::unique_ptr<RenderCommandFence> createCommandFence() override; | ||||
|         std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override; | ||||
|         std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override; | ||||
|         void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override; | ||||
|         void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override; | ||||
|         void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override; | ||||
|         const RenderDeviceCapabilities &getCapabilities() const override; | ||||
|         const RenderDeviceDescription &getDescription() const override; | ||||
|         RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override; | ||||
|         void waitIdle() const override; | ||||
|         void release(); | ||||
|         bool isValid() const; | ||||
|     }; | ||||
| 
 | ||||
|     struct D3D12Interface : RenderInterface { | ||||
|         IDXGIFactory4 *dxgiFactory = nullptr; | ||||
|         RenderInterfaceCapabilities capabilities; | ||||
|         std::vector<std::string> deviceNames; | ||||
| 
 | ||||
|         D3D12Interface(); | ||||
|         ~D3D12Interface() override; | ||||
|         std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override; | ||||
|         const RenderInterfaceCapabilities &getCapabilities() const override; | ||||
|         const std::vector<std::string> &getDeviceNames() const override; | ||||
|         bool isValid() const; | ||||
|     }; | ||||
| }; | ||||
|  | @ -1,262 +0,0 @@ | |||
| //
 | ||||
| // plume
 | ||||
| //
 | ||||
| // Copyright (c) 2024 renderbag and contributors. All rights reserved.
 | ||||
| // Licensed under the MIT license. See LICENSE file for details.
 | ||||
| //
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <climits> | ||||
| 
 | ||||
| #include "plume_render_interface_types.h" | ||||
| 
 | ||||
| namespace plume { | ||||
|     // Interfaces.
 | ||||
| 
 | ||||
|     struct RenderBufferFormattedView { | ||||
|         virtual ~RenderBufferFormattedView() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderBuffer { | ||||
|         virtual ~RenderBuffer() { } | ||||
|         virtual void *map(uint32_t subresource = 0, const RenderRange *readRange = nullptr) = 0; | ||||
|         virtual void unmap(uint32_t subresource = 0, const RenderRange *writtenRange = nullptr) = 0; | ||||
|         virtual std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) = 0; | ||||
|         virtual void setName(const std::string &name) = 0; | ||||
|         virtual uint64_t getDeviceAddress() const = 0; | ||||
| 
 | ||||
|         // Concrete implementation shortcuts.
 | ||||
|         inline RenderBufferReference at(uint64_t offset) const { | ||||
|             return RenderBufferReference(this, offset); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderTextureView { | ||||
|         virtual ~RenderTextureView() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderTexture { | ||||
|         virtual ~RenderTexture() { } | ||||
|         virtual std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) = 0; | ||||
|         virtual void setName(const std::string &name) = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderAccelerationStructure { | ||||
|         virtual ~RenderAccelerationStructure() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderShader { | ||||
|         virtual ~RenderShader() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderSampler { | ||||
|         virtual ~RenderSampler() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderPipeline { | ||||
|         virtual ~RenderPipeline() { } | ||||
|         virtual void setName(const std::string& name) const = 0; | ||||
|         virtual RenderPipelineProgram getProgram(const std::string &name) const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderPipelineLayout { | ||||
|         virtual ~RenderPipelineLayout() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderCommandFence { | ||||
|         virtual ~RenderCommandFence() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderCommandSemaphore { | ||||
|         virtual ~RenderCommandSemaphore() { } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderDescriptorSet { | ||||
|         // Descriptor indices correspond to the index assuming the descriptor set is one contiguous array. They DO NOT correspond to the bindings, which can be sparse.
 | ||||
|         // User code should derive these indices on its own by looking at the order the bindings were assigned during set creation along with the descriptor count and
 | ||||
|         // assume it was all allocated in one contiguous array. This allows efficient mapping between Vulkan and D3D12's descriptor models.
 | ||||
| 
 | ||||
|         virtual ~RenderDescriptorSet() { } | ||||
|         virtual void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) = 0; | ||||
|         virtual void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) = 0; | ||||
|         virtual void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) = 0; | ||||
|         virtual void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderSwapChain { | ||||
|         virtual ~RenderSwapChain() { } | ||||
|         virtual bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) = 0; | ||||
|         virtual void wait() = 0; | ||||
|         virtual bool resize() = 0; | ||||
|         virtual bool needsResize() const = 0; | ||||
|         virtual void setVsyncEnabled(bool vsyncEnabled) = 0; | ||||
|         virtual bool isVsyncEnabled() const = 0; | ||||
|         virtual uint32_t getWidth() const = 0; | ||||
|         virtual uint32_t getHeight() const = 0; | ||||
|         virtual RenderTexture *getTexture(uint32_t textureIndex) = 0; | ||||
|         virtual uint32_t getTextureCount() const = 0; | ||||
|         virtual bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) = 0; | ||||
|         virtual RenderWindow getWindow() const = 0; | ||||
|         virtual bool isEmpty() const = 0; | ||||
| 
 | ||||
|         // Only valid if displayTiming is enabled in capabilities.
 | ||||
|         virtual uint32_t getRefreshRate() const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderFramebuffer { | ||||
|         virtual ~RenderFramebuffer() { } | ||||
|         virtual uint32_t getWidth() const = 0; | ||||
|         virtual uint32_t getHeight() const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderCommandList { | ||||
|         virtual ~RenderCommandList() { } | ||||
|         virtual void begin() = 0; | ||||
|         virtual void end() = 0; | ||||
|         virtual void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) = 0; | ||||
|         virtual void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0; | ||||
|         virtual void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) = 0; | ||||
|         virtual void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) = 0; | ||||
|         virtual void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) = 0; | ||||
|         virtual void setPipeline(const RenderPipeline *pipeline) = 0; | ||||
|         virtual void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0; | ||||
|         virtual void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0; | ||||
|         virtual void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0; | ||||
|         virtual void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0; | ||||
|         virtual void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0; | ||||
|         virtual void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0; | ||||
|         virtual void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) = 0; | ||||
|         virtual void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0; | ||||
|         virtual void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0; | ||||
|         virtual void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0; | ||||
|         virtual void setIndexBuffer(const RenderIndexBufferView *view) = 0; | ||||
|         virtual void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) = 0; | ||||
|         virtual void setViewports(const RenderViewport *viewports, uint32_t count) = 0; | ||||
|         virtual void setScissors(const RenderRect *scissorRects, uint32_t count) = 0; | ||||
|         virtual void setFramebuffer(const RenderFramebuffer *framebuffer) = 0; | ||||
|         virtual void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) = 0; | ||||
|         virtual void clearColor(uint32_t attachmentIndex = 0, RenderColor colorValue = RenderColor(), const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0; | ||||
|         virtual void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0; | ||||
|         virtual void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) = 0; | ||||
|         virtual void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX = 0, uint32_t dstY = 0, uint32_t dstZ = 0, const RenderBox *srcBox = nullptr) = 0; | ||||
|         virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0; | ||||
|         virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0; | ||||
|         virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0; | ||||
|         virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr, RenderResolveMode resolveMode = RenderResolveMode::AVERAGE) = 0; | ||||
|         virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0; | ||||
|         virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0; | ||||
|         virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
 | ||||
|         virtual void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) = 0; | ||||
|         virtual void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) = 0; | ||||
| 
 | ||||
|         // Concrete implementation shortcuts.
 | ||||
|         inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &barrier) { | ||||
|             barriers(stages, &barrier, 1, nullptr, 0); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier &barrier) { | ||||
|             barriers(stages, nullptr, 0, &barrier, 1); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &bufferBarrier, const RenderTextureBarrier &textureBarrier) { | ||||
|             barriers(stages, &bufferBarrier, 1, &textureBarrier, 1); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount) { | ||||
|             barriers(stages, bufferBarriers, bufferBarriersCount, nullptr, 0); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers) { | ||||
|             barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), nullptr, 0); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) { | ||||
|             barriers(stages, nullptr, 0, textureBarriers, textureBarriersCount); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const std::vector<RenderTextureBarrier> &textureBarriers) { | ||||
|             barriers(stages, nullptr, 0, textureBarriers.data(), uint32_t(textureBarriers.size())); | ||||
|         } | ||||
| 
 | ||||
|         inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers, const std::vector<RenderTextureBarrier> &textureBarriers) { | ||||
|             barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), textureBarriers.data(), uint32_t(textureBarriers.size())); | ||||
|         } | ||||
| 
 | ||||
|         inline void setViewports(const RenderViewport &viewport) { | ||||
|             setViewports(&viewport, 1); | ||||
|         } | ||||
| 
 | ||||
|         inline void setScissors(const RenderRect &scissorRect) { | ||||
|             setScissors(&scissorRect, 1); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderCommandQueue { | ||||
|         virtual ~RenderCommandQueue() { } | ||||
|         virtual std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) = 0; | ||||
|         virtual void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores = nullptr, uint32_t waitSemaphoreCount = 0, RenderCommandSemaphore **signalSemaphores = nullptr, uint32_t signalSemaphoreCount = 0, RenderCommandFence *signalFence = nullptr) = 0; | ||||
|         virtual void waitForCommandFence(RenderCommandFence *fence) = 0; | ||||
| 
 | ||||
|         // Concrete implementation shortcuts.
 | ||||
|         inline void executeCommandLists(const RenderCommandList *commandList, RenderCommandFence *signalFence = nullptr) { | ||||
|             executeCommandLists(commandList != nullptr ? &commandList : nullptr, commandList != nullptr ? 1 : 0, nullptr, 0, nullptr, 0, signalFence); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderPool { | ||||
|         virtual ~RenderPool() { } | ||||
|         virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderQueryPool { | ||||
|         virtual ~RenderQueryPool() { } | ||||
|         virtual void queryResults() = 0; | ||||
|         virtual const uint64_t *getResults() const = 0; | ||||
|         virtual uint32_t getCount() const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderDevice { | ||||
|         virtual ~RenderDevice() { } | ||||
|         virtual std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) = 0; | ||||
|         virtual std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) = 0; | ||||
|         virtual std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline = nullptr) = 0; | ||||
|         virtual std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) = 0; | ||||
|         virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderCommandFence> createCommandFence() = 0; | ||||
|         virtual std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() = 0; | ||||
|         virtual std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) = 0; | ||||
|         virtual std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) = 0; | ||||
|         virtual void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0; | ||||
|         virtual void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0; | ||||
|         virtual void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) = 0; | ||||
|         virtual const RenderDeviceCapabilities &getCapabilities() const = 0; | ||||
|         virtual const RenderDeviceDescription &getDescription() const = 0; | ||||
|         virtual RenderSampleCounts getSampleCountsSupported(RenderFormat format) const = 0; | ||||
|         virtual void waitIdle() const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderInterface { | ||||
|         virtual ~RenderInterface() { } | ||||
|         virtual std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName = "") = 0; | ||||
|         virtual const std::vector<std::string> &getDeviceNames() const = 0; | ||||
|         virtual const RenderInterfaceCapabilities &getCapabilities() const = 0; | ||||
|     }; | ||||
| 
 | ||||
|     extern void RenderInterfaceTest(RenderInterface *renderInterface); | ||||
|     extern void TestInitialize(RenderInterface* renderInterface, RenderWindow window); | ||||
|     extern void TestDraw(); | ||||
|     extern void TestResize(); | ||||
|     extern void TestShutdown(); | ||||
| }; | ||||
| 
 | ||||
| #include "plume_render_interface_builders.h" | ||||
|  | @ -1,281 +0,0 @@ | |||
| //
 | ||||
| // plume
 | ||||
| //
 | ||||
| // Copyright (c) 2024 renderbag and contributors. All rights reserved.
 | ||||
| // Licensed under the MIT license. See LICENSE file for details.
 | ||||
| //
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <unordered_set> | ||||
| 
 | ||||
| namespace plume { | ||||
|     struct RenderDescriptorSetBuilder { | ||||
|         std::list<std::vector<const RenderSampler *>> samplerPointerVectorList; | ||||
|         std::vector<RenderDescriptorRange> descriptorRanges; | ||||
|         RenderDescriptorSetDesc descriptorSetDesc; | ||||
|         bool open = false; | ||||
|         uint32_t setIndex = 0; | ||||
| 
 | ||||
|         RenderDescriptorSetBuilder() = default; | ||||
| 
 | ||||
|         void begin() { | ||||
|             assert(!open && "Builder must be closed."); | ||||
| 
 | ||||
|             descriptorSetDesc = RenderDescriptorSetDesc(); | ||||
| 
 | ||||
|             samplerPointerVectorList.clear(); | ||||
|             descriptorRanges.clear(); | ||||
| 
 | ||||
|             open = true; | ||||
|             setIndex = 0; | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addConstantBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::CONSTANT_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addFormattedBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::FORMATTED_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addReadWriteFormattedBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_FORMATTED_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addTexture(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::TEXTURE, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addReadWriteTexture(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_TEXTURE, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addSampler(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addImmutableSampler(uint32_t binding, const RenderSampler *immutableSampler) { | ||||
|             assert(immutableSampler != nullptr); | ||||
| 
 | ||||
|             return addImmutableSampler(binding, &immutableSampler); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addImmutableSampler(uint32_t binding, const RenderSampler **immutableSampler, uint32_t count = 1) { | ||||
|             assert(immutableSampler != nullptr); | ||||
| 
 | ||||
|             samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + count)); | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, samplerPointerVectorList.back().data())); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addStructuredBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::STRUCTURED_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addReadWriteStructuredBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_STRUCTURED_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addByteAddressBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::BYTE_ADDRESS_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addReadWriteByteAddressBuffer(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_BYTE_ADDRESS_BUFFER, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addAccelerationStructure(uint32_t binding, uint32_t count = 1) { | ||||
|             return addRange(RenderDescriptorRange(RenderDescriptorRangeType::ACCELERATION_STRUCTURE, binding, count, nullptr)); | ||||
|         } | ||||
| 
 | ||||
|         uint32_t addRange(const RenderDescriptorRange &range) { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             uint32_t returnValue = setIndex; | ||||
|             descriptorRanges.emplace_back(range); | ||||
|             descriptorSetDesc.descriptorRangesCount++; | ||||
|             setIndex += range.count; | ||||
|             return returnValue; | ||||
|         } | ||||
| 
 | ||||
|         void end(bool lastRangeIsBoundless = false, uint32_t boundlessRangeSize = 0) { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             descriptorSetDesc.lastRangeIsBoundless = lastRangeIsBoundless; | ||||
|             descriptorSetDesc.boundlessRangeSize = boundlessRangeSize; | ||||
|             descriptorSetDesc.descriptorRanges = descriptorRanges.data(); | ||||
|             open = false; | ||||
|         } | ||||
| 
 | ||||
|         std::unique_ptr<RenderDescriptorSet> create(RenderDevice *device) const { | ||||
|             assert(!open && "Builder must be closed."); | ||||
| 
 | ||||
|             return device->createDescriptorSet(descriptorSetDesc); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderDescriptorSetBase { | ||||
|         RenderDescriptorSetBuilder builder; | ||||
|         std::unique_ptr<RenderDescriptorSet> descriptorSet; | ||||
| 
 | ||||
|         void create(RenderDevice *device) { | ||||
|             descriptorSet = builder.create(device); | ||||
|         } | ||||
| 
 | ||||
|         RenderDescriptorSet *get() const { | ||||
|             return descriptorSet.get(); | ||||
|         } | ||||
| 
 | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) { | ||||
|             descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, bufferStructuredView, bufferFormattedView); | ||||
|         } | ||||
| 
 | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView &bufferStructuredView) { | ||||
|             descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, &bufferStructuredView); | ||||
|         } | ||||
| 
 | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferFormattedView *bufferFormattedView) { | ||||
|             descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, nullptr, bufferFormattedView); | ||||
|         } | ||||
| 
 | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferStructuredView &bufferStructuredView) { | ||||
|             descriptorSet->setBuffer(descriptorIndex, buffer, 0, &bufferStructuredView); | ||||
|         } | ||||
| 
 | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferFormattedView *bufferFormattedView) { | ||||
|             descriptorSet->setBuffer(descriptorIndex, buffer, 0, nullptr, bufferFormattedView); | ||||
|         } | ||||
| 
 | ||||
|         void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, const RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) { | ||||
|             descriptorSet->setTexture(descriptorIndex, texture, textureLayout, textureView); | ||||
|         } | ||||
| 
 | ||||
|         void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) { | ||||
|             descriptorSet->setSampler(descriptorIndex, sampler); | ||||
|         } | ||||
| 
 | ||||
|         void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) { | ||||
|             descriptorSet->setAccelerationStructure(descriptorIndex, accelerationStructure); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     struct RenderDescriptorSetInclusionFilter { | ||||
|         const uint32_t *bindings = nullptr; | ||||
|         uint32_t bindingsCount = 0; | ||||
|     }; | ||||
|      | ||||
|     struct RenderPipelineLayoutBuilder { | ||||
|         std::vector<RenderPushConstantRange> pushConstantRanges; | ||||
|         std::list<std::vector<const RenderSampler *>> samplerPointerVectorList; | ||||
|         std::vector<RenderDescriptorRange> descriptorRanges; | ||||
|         std::vector<RenderDescriptorSetDesc> descriptorSetDescs; | ||||
|         std::vector<uint32_t> descriptorRangeIndexPerSet; | ||||
|         std::vector<RenderRootDescriptorDesc> rootDescriptorDescs; | ||||
|         RenderPipelineLayoutDesc layoutDesc; | ||||
|         bool open = false; | ||||
| 
 | ||||
|         // Start filling the description.
 | ||||
|         void begin(bool isLocal = false, bool allowInputLayout = false) { | ||||
|             assert(!open && "Builder must be closed."); | ||||
| 
 | ||||
|             layoutDesc = RenderPipelineLayoutDesc(); | ||||
|             layoutDesc.isLocal = isLocal; | ||||
|             layoutDesc.allowInputLayout = allowInputLayout; | ||||
| 
 | ||||
|             pushConstantRanges.clear(); | ||||
|             samplerPointerVectorList.clear(); | ||||
|             descriptorRanges.clear(); | ||||
|             descriptorSetDescs.clear(); | ||||
|             descriptorRangeIndexPerSet.clear(); | ||||
|             rootDescriptorDescs.clear(); | ||||
| 
 | ||||
|             open = true; | ||||
|         } | ||||
| 
 | ||||
|         // Returns push constant index.
 | ||||
|         uint32_t addPushConstant(uint32_t binding, uint32_t set, uint32_t size, RenderShaderStageFlags stageFlags, uint32_t offset = 0) { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             uint32_t returnValue = layoutDesc.pushConstantRangesCount; | ||||
|             pushConstantRanges.emplace_back(RenderPushConstantRange(binding, set, offset, size, stageFlags)); | ||||
|             layoutDesc.pushConstantRangesCount++; | ||||
|             return returnValue; | ||||
|         } | ||||
| 
 | ||||
|         // Returns set index.
 | ||||
|         uint32_t addDescriptorSet(const RenderDescriptorSetDesc &descriptorSetDesc) { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             uint32_t returnValue = layoutDesc.descriptorSetDescsCount; | ||||
|             descriptorRangeIndexPerSet.emplace_back(uint32_t(descriptorRanges.size())); | ||||
|             descriptorSetDescs.emplace_back(descriptorSetDesc); | ||||
| 
 | ||||
|             for (uint32_t j = 0; j < descriptorSetDesc.descriptorRangesCount; j++) { | ||||
|                 descriptorRanges.emplace_back(descriptorSetDesc.descriptorRanges[j]); | ||||
| 
 | ||||
|                 // Copy the immutable sampler pointers to a local vector list.
 | ||||
|                 if (descriptorRanges.back().immutableSampler != nullptr) { | ||||
|                     const RenderSampler **immutableSampler = descriptorRanges.back().immutableSampler; | ||||
|                     samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + descriptorRanges.back().count)); | ||||
|                     descriptorRanges.back().immutableSampler = samplerPointerVectorList.back().data(); | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             layoutDesc.descriptorSetDescsCount++; | ||||
| 
 | ||||
|             return returnValue; | ||||
|         } | ||||
| 
 | ||||
|         // Returns set index.
 | ||||
|         uint32_t addDescriptorSet(const RenderDescriptorSetBuilder &descriptorSetBuilder) { | ||||
|             return addDescriptorSet(descriptorSetBuilder.descriptorSetDesc); | ||||
|         } | ||||
| 
 | ||||
|         // Returns set index.
 | ||||
|         uint32_t addDescriptorSet(const RenderDescriptorSetBase &descriptorSetBase) { | ||||
|             return addDescriptorSet(descriptorSetBase.builder); | ||||
|         } | ||||
| 
 | ||||
|         // Returns root descriptor index. D3D12 only.
 | ||||
|         uint32_t addRootDescriptor(uint32_t shaderRegister, uint32_t registerSpace, RenderRootDescriptorType type) { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             uint32_t returnValue = layoutDesc.rootDescriptorDescsCount; | ||||
|             rootDescriptorDescs.emplace_back(shaderRegister, registerSpace, type); | ||||
|             ++layoutDesc.rootDescriptorDescsCount; | ||||
| 
 | ||||
|             return returnValue; | ||||
|         } | ||||
| 
 | ||||
|         // Finish the description.
 | ||||
|         void end() { | ||||
|             assert(open && "Builder must be open."); | ||||
| 
 | ||||
|             if (layoutDesc.pushConstantRangesCount > 0) { | ||||
|                 layoutDesc.pushConstantRanges = pushConstantRanges.data(); | ||||
|             } | ||||
| 
 | ||||
|             if (layoutDesc.descriptorSetDescsCount > 0) { | ||||
|                 for (uint32_t i = 0; i < layoutDesc.descriptorSetDescsCount; i++) { | ||||
|                     const uint32_t rangeIndex = descriptorRangeIndexPerSet[i]; | ||||
|                     descriptorSetDescs[i].descriptorRanges = &descriptorRanges[rangeIndex]; | ||||
|                 } | ||||
| 
 | ||||
|                 layoutDesc.descriptorSetDescs = descriptorSetDescs.data(); | ||||
|             } | ||||
| 
 | ||||
|             if (layoutDesc.rootDescriptorDescsCount > 0) { | ||||
|                 layoutDesc.rootDescriptorDescs = rootDescriptorDescs.data(); | ||||
|             } | ||||
| 
 | ||||
|             open = false; | ||||
|         } | ||||
| 
 | ||||
|         // Create a pipeline layout with the final description.
 | ||||
|         std::unique_ptr<RenderPipelineLayout> create(RenderDevice *device) const { | ||||
|             assert(!open && "Builder must be closed."); | ||||
| 
 | ||||
|             return device->createPipelineLayout(layoutDesc); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,456 +0,0 @@ | |||
| //
 | ||||
| // plume
 | ||||
| //
 | ||||
| // Copyright (c) 2024 renderbag and contributors. All rights reserved.
 | ||||
| // Licensed under the MIT license. See LICENSE file for details.
 | ||||
| //
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "plume_render_interface.h" | ||||
| 
 | ||||
| #include <mutex> | ||||
| #include <set> | ||||
| #include <unordered_map> | ||||
| #include <unordered_set> | ||||
| 
 | ||||
| #if defined(_WIN64) | ||||
| #define VK_USE_PLATFORM_WIN32_KHR | ||||
| #elif defined(__ANDROID__) | ||||
| #define VK_USE_PLATFORM_ANDROID_KHR | ||||
| #elif defined(__linux__) | ||||
| #define VK_USE_PLATFORM_XLIB_KHR | ||||
| #endif | ||||
| 
 | ||||
| #include <volk.h> | ||||
| 
 | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wnullability-completeness" | ||||
| #endif | ||||
| 
 | ||||
| #include <vk_mem_alloc.h> | ||||
| 
 | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic pop | ||||
| #endif | ||||
| 
 | ||||
| namespace plume { | ||||
|     struct VulkanCommandQueue; | ||||
|     struct VulkanDevice; | ||||
|     struct VulkanInterface; | ||||
|     struct VulkanPool; | ||||
|     struct VulkanQueue; | ||||
| 
 | ||||
|     struct VulkanBuffer : RenderBuffer { | ||||
|         VkBuffer vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         VulkanPool *pool = nullptr; | ||||
|         VmaAllocation allocation = VK_NULL_HANDLE; | ||||
|         VmaAllocationInfo allocationInfo = {}; | ||||
|         RenderBufferDesc desc; | ||||
|         RenderBarrierStages barrierStages = RenderBarrierStage::NONE; | ||||
| 
 | ||||
|         VulkanBuffer() = default; | ||||
|         VulkanBuffer(VulkanDevice *device, VulkanPool *pool, const RenderBufferDesc &desc); | ||||
|         ~VulkanBuffer() override; | ||||
|         void *map(uint32_t subresource, const RenderRange *readRange) override; | ||||
|         void unmap(uint32_t subresource, const RenderRange *writtenRange) override; | ||||
|         std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override; | ||||
|         void setName(const std::string &name) override; | ||||
|         uint64_t getDeviceAddress() const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanBufferFormattedView : RenderBufferFormattedView { | ||||
|         VkBufferView vk = VK_NULL_HANDLE; | ||||
|         VulkanBuffer *buffer = nullptr; | ||||
| 
 | ||||
|         VulkanBufferFormattedView(VulkanBuffer *buffer, RenderFormat format); | ||||
|         ~VulkanBufferFormattedView() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanTexture : RenderTexture { | ||||
|         VkImage vk = VK_NULL_HANDLE; | ||||
|         VkImageView imageView = VK_NULL_HANDLE; | ||||
|         VkFormat imageFormat = VK_FORMAT_UNDEFINED; | ||||
|         VkImageSubresourceRange imageSubresourceRange = {}; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         VulkanPool *pool = nullptr; | ||||
|         VmaAllocation allocation = VK_NULL_HANDLE; | ||||
|         VmaAllocationInfo allocationInfo = {}; | ||||
|         RenderTextureLayout textureLayout = RenderTextureLayout::UNKNOWN; | ||||
|         RenderBarrierStages barrierStages = RenderBarrierStage::NONE; | ||||
|         bool ownership = false; | ||||
|         RenderTextureDesc desc; | ||||
| 
 | ||||
|         VulkanTexture() = default; | ||||
|         VulkanTexture(VulkanDevice *device, VulkanPool *pool, const RenderTextureDesc &desc); | ||||
|         VulkanTexture(VulkanDevice *device, VkImage image); | ||||
|         ~VulkanTexture() override; | ||||
|         void createImageView(VkFormat format); | ||||
|         std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override; | ||||
|         void setName(const std::string &name) override; | ||||
|         void fillSubresourceRange(); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanTextureView : RenderTextureView { | ||||
|         VkImageView vk = VK_NULL_HANDLE; | ||||
|         VulkanTexture *texture = nullptr; | ||||
| 
 | ||||
|         VulkanTextureView(VulkanTexture *texture, const RenderTextureViewDesc &desc); | ||||
|         ~VulkanTextureView() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanAccelerationStructure : RenderAccelerationStructure { | ||||
|         VkAccelerationStructureKHR vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN; | ||||
| 
 | ||||
|         VulkanAccelerationStructure(VulkanDevice *device, const RenderAccelerationStructureDesc &desc); | ||||
|         ~VulkanAccelerationStructure() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanDescriptorSetLayout { | ||||
|         VkDescriptorSetLayout vk = VK_NULL_HANDLE; | ||||
|         std::vector<VkDescriptorSetLayoutBinding> setBindings; | ||||
|         std::vector<uint32_t> descriptorIndexBases; | ||||
|         std::vector<uint32_t> descriptorBindingIndices; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanDescriptorSetLayout(VulkanDevice *device, const RenderDescriptorSetDesc &descriptorSetDesc); | ||||
|         ~VulkanDescriptorSetLayout(); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanPipelineLayout : RenderPipelineLayout { | ||||
|         VkPipelineLayout vk = VK_NULL_HANDLE; | ||||
|         std::vector<VkPushConstantRange> pushConstantRanges; | ||||
|         std::vector<VulkanDescriptorSetLayout *> descriptorSetLayouts; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanPipelineLayout(VulkanDevice *device, const RenderPipelineLayoutDesc &desc); | ||||
|         ~VulkanPipelineLayout() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanShader : RenderShader { | ||||
|         VkShaderModule vk = VK_NULL_HANDLE; | ||||
|         std::string entryPointName; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         RenderShaderFormat format = RenderShaderFormat::UNKNOWN; | ||||
| 
 | ||||
|         VulkanShader(VulkanDevice *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format); | ||||
|         ~VulkanShader() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanSampler : RenderSampler { | ||||
|         VkSampler vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanSampler(VulkanDevice *device, const RenderSamplerDesc &desc); | ||||
|         ~VulkanSampler(); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanPipeline : RenderPipeline { | ||||
|         enum class Type { | ||||
|             Unknown, | ||||
|             Compute, | ||||
|             Graphics, | ||||
|             Raytracing | ||||
|         }; | ||||
| 
 | ||||
|         VulkanDevice *device = nullptr; | ||||
|         Type type = Type::Unknown; | ||||
| 
 | ||||
|         VulkanPipeline(VulkanDevice *device, Type type); | ||||
|         virtual ~VulkanPipeline() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanComputePipeline : VulkanPipeline { | ||||
|         VkPipeline vk = VK_NULL_HANDLE; | ||||
|         VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; | ||||
| 
 | ||||
|         VulkanComputePipeline(VulkanDevice *device, const RenderComputePipelineDesc &desc); | ||||
|         ~VulkanComputePipeline() override; | ||||
|         void setName(const std::string& name) const override; | ||||
|         RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanGraphicsPipeline : VulkanPipeline { | ||||
|         VkPipeline vk = VK_NULL_HANDLE; | ||||
|         VkRenderPass renderPass = VK_NULL_HANDLE; | ||||
| 
 | ||||
|         VulkanGraphicsPipeline(VulkanDevice *device, const RenderGraphicsPipelineDesc &desc); | ||||
|         ~VulkanGraphicsPipeline() override; | ||||
|         void setName(const std::string& name) const override; | ||||
|         RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|         static VkRenderPass createRenderPass(VulkanDevice *device, const VkFormat *renderTargetFormat, uint32_t renderTargetCount, VkFormat depthTargetFormat, VkSampleCountFlagBits sampleCount); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanRaytracingPipeline : VulkanPipeline { | ||||
|         VkPipeline vk = VK_NULL_HANDLE; | ||||
|         std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap; | ||||
|         uint32_t groupCount = 0; | ||||
|         uint32_t descriptorSetCount = 0; | ||||
| 
 | ||||
|         VulkanRaytracingPipeline(VulkanDevice *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline); | ||||
|         ~VulkanRaytracingPipeline() override; | ||||
|         void setName(const std::string& name) const override; | ||||
|         RenderPipelineProgram getProgram(const std::string &name) const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanDescriptorSet : RenderDescriptorSet { | ||||
|         VkDescriptorSet vk = VK_NULL_HANDLE; | ||||
|         VulkanDescriptorSetLayout *setLayout = nullptr; | ||||
|         VkDescriptorPool descriptorPool = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanDescriptorSet(VulkanDevice *device, const RenderDescriptorSetDesc &desc); | ||||
|         ~VulkanDescriptorSet() override; | ||||
|         void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override; | ||||
|         void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override; | ||||
|         void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override; | ||||
|         void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override; | ||||
|         void setDescriptor(uint32_t descriptorIndex, const VkDescriptorBufferInfo *bufferInfo, const VkDescriptorImageInfo *imageInfo, const VkBufferView *texelBufferView, void *pNext); | ||||
|         static VkDescriptorPool createDescriptorPool(VulkanDevice *device, const std::unordered_map<VkDescriptorType, uint32_t> &typeCounts, bool lastRangeIsBoundless); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanSwapChain : RenderSwapChain { | ||||
|         VkSwapchainKHR vk = VK_NULL_HANDLE; | ||||
|         VulkanCommandQueue *commandQueue = nullptr; | ||||
|         VkSurfaceKHR surface = VK_NULL_HANDLE; | ||||
|         RenderWindow renderWindow = {}; | ||||
|         uint32_t textureCount = 0; | ||||
|         uint64_t presentCount = 0; | ||||
|         RenderFormat format = RenderFormat::UNKNOWN; | ||||
|         uint32_t width = 0; | ||||
|         uint32_t height = 0; | ||||
|         VkSwapchainCreateInfoKHR createInfo = {}; | ||||
|         VkSurfaceFormatKHR pickedSurfaceFormat = {}; | ||||
|         VkPresentModeKHR createdPresentMode = VK_PRESENT_MODE_FIFO_KHR; | ||||
|         VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR; | ||||
|         VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; | ||||
|         std::vector<VulkanTexture> textures; | ||||
|         uint64_t currentPresentId = 0; | ||||
|         bool immediatePresentModeSupported = false; | ||||
|         uint32_t maxFrameLatency = 0; | ||||
| 
 | ||||
|         VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency); | ||||
|         ~VulkanSwapChain() override; | ||||
|         bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override; | ||||
|         void wait() override; | ||||
|         bool resize() override; | ||||
|         bool needsResize() const override; | ||||
|         void setVsyncEnabled(bool vsyncEnabled) override; | ||||
|         bool isVsyncEnabled() const override; | ||||
|         uint32_t getWidth() const override; | ||||
|         uint32_t getHeight() const override; | ||||
|         RenderTexture *getTexture(uint32_t textureIndex) override; | ||||
|         uint32_t getTextureCount() const override; | ||||
|         bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override; | ||||
|         RenderWindow getWindow() const override; | ||||
|         bool isEmpty() const override; | ||||
|         uint32_t getRefreshRate() const override; | ||||
|         void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const; | ||||
|         void releaseSwapChain(); | ||||
|         void releaseImageViews(); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanFramebuffer : RenderFramebuffer { | ||||
|         VulkanDevice *device = nullptr; | ||||
|         VkFramebuffer vk = VK_NULL_HANDLE; | ||||
|         VkRenderPass renderPass = VK_NULL_HANDLE; | ||||
|         std::vector<const VulkanTexture *> colorAttachments; | ||||
|         const VulkanTexture *depthAttachment = nullptr; | ||||
|         bool depthAttachmentReadOnly = false; | ||||
|         uint32_t width = 0; | ||||
|         uint32_t height = 0; | ||||
| 
 | ||||
|         VulkanFramebuffer(VulkanDevice *device, const RenderFramebufferDesc &desc); | ||||
|         ~VulkanFramebuffer() override; | ||||
|         uint32_t getWidth() const override; | ||||
|         uint32_t getHeight() const override; | ||||
|         bool contains(const VulkanTexture *attachment) const; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanQueryPool : RenderQueryPool { | ||||
|         VulkanDevice *device = nullptr; | ||||
|         std::vector<uint64_t> results; | ||||
|         VkQueryPool vk = VK_NULL_HANDLE; | ||||
| 
 | ||||
|         VulkanQueryPool(VulkanDevice *device, uint32_t queryCount); | ||||
|         virtual ~VulkanQueryPool() override; | ||||
|         virtual void queryResults() override; | ||||
|         virtual const uint64_t *getResults() const override; | ||||
|         virtual uint32_t getCount() const override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanCommandList : RenderCommandList { | ||||
|         VkCommandBuffer vk = VK_NULL_HANDLE; | ||||
|         VkCommandPool commandPool = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         RenderCommandListType type = RenderCommandListType::UNKNOWN; | ||||
|         const VulkanFramebuffer *targetFramebuffer = nullptr; | ||||
|         const VulkanPipelineLayout *activeComputePipelineLayout = nullptr; | ||||
|         const VulkanPipelineLayout *activeGraphicsPipelineLayout = nullptr; | ||||
|         const VulkanPipelineLayout *activeRaytracingPipelineLayout = nullptr; | ||||
|         VkRenderPass activeRenderPass = VK_NULL_HANDLE; | ||||
| 
 | ||||
|         VulkanCommandList(VulkanDevice *device, RenderCommandListType type); | ||||
|         ~VulkanCommandList() override; | ||||
|         void begin() override; | ||||
|         void end() override; | ||||
|         void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override; | ||||
|         void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override; | ||||
|         void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override; | ||||
|         void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override; | ||||
|         void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override; | ||||
|         void setPipeline(const RenderPipeline *pipeline) override; | ||||
|         void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override; | ||||
|         void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override; | ||||
|         void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override; | ||||
|         void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override; | ||||
|         void setIndexBuffer(const RenderIndexBufferView *view) override; | ||||
|         void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override; | ||||
|         void setViewports(const RenderViewport *viewports, uint32_t count) override; | ||||
|         void setScissors(const RenderRect *scissorRects, uint32_t count) override; | ||||
|         void setFramebuffer(const RenderFramebuffer *framebuffer) override; | ||||
|         void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override; | ||||
|         void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override; | ||||
|         void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override; | ||||
|         void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override; | ||||
|         void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override; | ||||
|         void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override; | ||||
|         void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override; | ||||
|         void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override; | ||||
|         void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override; | ||||
|         void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override; | ||||
|         void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override; | ||||
|         void discardTexture(const RenderTexture* texture) override; | ||||
|         void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override; | ||||
|         void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override; | ||||
|         void checkActiveRenderPass(); | ||||
|         void endActiveRenderPass(); | ||||
|         void setDescriptorSet(VkPipelineBindPoint bindPoint, const VulkanPipelineLayout *pipelineLayout, const RenderDescriptorSet *descriptorSet, uint32_t setIndex); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanCommandFence : RenderCommandFence { | ||||
|         VkFence vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanCommandFence(VulkanDevice *device); | ||||
|         ~VulkanCommandFence() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanCommandSemaphore : RenderCommandSemaphore { | ||||
|         VkSemaphore vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanCommandSemaphore(VulkanDevice *device); | ||||
|         ~VulkanCommandSemaphore() override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanCommandQueue : RenderCommandQueue { | ||||
|         VulkanQueue *queue = nullptr; | ||||
|         VulkanDevice *device = nullptr; | ||||
|         uint32_t familyIndex = 0; | ||||
|         uint32_t queueIndex = 0; | ||||
|         std::unordered_set<VulkanSwapChain *> swapChains; | ||||
| 
 | ||||
|         VulkanCommandQueue(VulkanDevice *device, RenderCommandListType commandListType); | ||||
|         ~VulkanCommandQueue() override; | ||||
|         std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) override; | ||||
|         void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override; | ||||
|         void waitForCommandFence(RenderCommandFence *fence) override; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanPool : RenderPool { | ||||
|         VmaPool vk = VK_NULL_HANDLE; | ||||
|         VulkanDevice *device = nullptr; | ||||
| 
 | ||||
|         VulkanPool(VulkanDevice *device, const RenderPoolDesc &desc); | ||||
|         ~VulkanPool() override; | ||||
|         std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override; | ||||
|     }; | ||||
|      | ||||
|     struct VulkanQueue { | ||||
|         VkQueue vk; | ||||
|         std::unique_ptr<std::mutex> mutex; | ||||
|         std::unordered_set<const VulkanCommandQueue *> virtualQueues; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanQueueFamily { | ||||
|         std::vector<VulkanQueue> queues; | ||||
| 
 | ||||
|         void add(VulkanCommandQueue *virtualQueue); | ||||
|         void remove(VulkanCommandQueue *virtualQueue); | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanDevice : RenderDevice { | ||||
|         VkDevice vk = VK_NULL_HANDLE; | ||||
|         VulkanInterface *renderInterface = nullptr; | ||||
|         VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; | ||||
|         VkPhysicalDeviceProperties physicalDeviceProperties = {}; | ||||
|         VmaAllocator allocator = VK_NULL_HANDLE; | ||||
|         uint32_t queueFamilyIndices[3] = {}; | ||||
|         std::vector<VulkanQueueFamily> queueFamilies; | ||||
|         RenderDeviceCapabilities capabilities; | ||||
|         RenderDeviceDescription description; | ||||
|         VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {}; | ||||
|         VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {}; | ||||
|         bool loadStoreOpNoneSupported = false; | ||||
| 
 | ||||
|         VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName); | ||||
|         ~VulkanDevice() override; | ||||
|         std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override; | ||||
|         std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override; | ||||
|         std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override; | ||||
|         std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override; | ||||
|         std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override; | ||||
|         std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override; | ||||
|         std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override; | ||||
|         std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override; | ||||
|         std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override; | ||||
|         std::unique_ptr<RenderCommandFence> createCommandFence() override; | ||||
|         std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override; | ||||
|         std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override; | ||||
|         std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override; | ||||
|         void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override; | ||||
|         void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override; | ||||
|         void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override; | ||||
|         const RenderDeviceCapabilities &getCapabilities() const override; | ||||
|         const RenderDeviceDescription &getDescription() const override; | ||||
|         RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override; | ||||
|         void waitIdle() const override; | ||||
|         void release(); | ||||
|         bool isValid() const; | ||||
|     }; | ||||
| 
 | ||||
|     struct VulkanInterface : RenderInterface { | ||||
|         VkInstance instance = VK_NULL_HANDLE; | ||||
|         VkApplicationInfo appInfo = {}; | ||||
|         RenderInterfaceCapabilities capabilities; | ||||
|         std::vector<std::string> deviceNames; | ||||
| 
 | ||||
| #   if SDL_VULKAN_ENABLED | ||||
|         VulkanInterface(RenderWindow sdlWindow); | ||||
| #   else | ||||
|         VulkanInterface(); | ||||
| #   endif | ||||
| 
 | ||||
|         ~VulkanInterface() override; | ||||
|         std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override; | ||||
|         const RenderInterfaceCapabilities &getCapabilities() const override; | ||||
|         const std::vector<std::string> &getDeviceNames() const override; | ||||
|         bool isValid() const; | ||||
|     }; | ||||
| }; | ||||
|  | @ -37,6 +37,7 @@ | |||
| #include <magic_enum/magic_enum.hpp> | ||||
| #endif | ||||
| 
 | ||||
| #define UNLEASHED_RECOMP | ||||
| #include "../../tools/XenosRecomp/XenosRecomp/shader_common.h" | ||||
| 
 | ||||
| #ifdef UNLEASHED_RECOMP_D3D12 | ||||
|  | @ -1837,7 +1838,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) | |||
|     g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT); | ||||
| 
 | ||||
|     for (auto& commandList : g_commandLists) | ||||
|         commandList = g_device->createCommandList(RenderCommandListType::DIRECT); | ||||
|         commandList = g_queue->createCommandList(); | ||||
| 
 | ||||
|     for (auto& commandFence : g_commandFences) | ||||
|         commandFence = g_device->createCommandFence(); | ||||
|  | @ -1846,7 +1847,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry) | |||
|         queryPool = g_device->createQueryPool(NUM_QUERIES); | ||||
| 
 | ||||
|     g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY); | ||||
|     g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY); | ||||
|     g_copyCommandList = g_copyQueue->createCommandList(); | ||||
|     g_copyCommandFence = g_device->createCommandFence(); | ||||
| 
 | ||||
|     uint32_t bufferCount = 2; | ||||
|  | @ -2074,23 +2075,21 @@ void Video::WaitForGPU() | |||
| { | ||||
|     g_waitForGPUCount++; | ||||
| 
 | ||||
|     if (g_vulkan) | ||||
|     // Wait for all queued frames to finish.
 | ||||
|     for (size_t i = 0; i < NUM_FRAMES; i++) | ||||
|     { | ||||
|         g_device->waitIdle(); | ||||
|     } | ||||
|     else  | ||||
|     { | ||||
|         for (size_t i = 0; i < NUM_FRAMES; i++) | ||||
|         if (g_commandListStates[i]) | ||||
|         { | ||||
|             if (g_commandListStates[i]) | ||||
|             { | ||||
|                 g_queue->waitForCommandFence(g_commandFences[i].get()); | ||||
|                 g_commandListStates[i] = false; | ||||
|             } | ||||
|             g_queue->waitForCommandFence(g_commandFences[i].get()); | ||||
|             g_commandListStates[i] = false; | ||||
|         } | ||||
|         g_queue->executeCommandLists(nullptr, g_commandFences[0].get()); | ||||
|         g_queue->waitForCommandFence(g_commandFences[0].get()); | ||||
|     } | ||||
| 
 | ||||
|     // Execute an empty command list and wait for it to end to guarantee that any remaining presentation has finished.
 | ||||
|     g_commandLists[0]->begin(); | ||||
|     g_commandLists[0]->end(); | ||||
|     g_queue->executeCommandLists(g_commandLists[0].get(), g_commandFences[0].get()); | ||||
|     g_queue->waitForCommandFence(g_commandFences[0].get()); | ||||
| } | ||||
| 
 | ||||
| static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6) | ||||
|  | @ -5736,7 +5735,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS | |||
|                 auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex) | ||||
|                     { | ||||
|                         g_copyCommandList->copyTextureRegion( | ||||
|                             RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex), | ||||
|                             RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % ddsDesc.numMips, subresourceIndex / ddsDesc.numMips), | ||||
|                             RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset)); | ||||
|                     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| /////////////////////////////////////////////////////////////////////#define PSO_CACHING
 | ||||
| //#define PSO_CACHING_CLEANUP
 | ||||
| 
 | ||||
| #include "rhi/plume_render_interface.h" | ||||
| #include <plume_render_interface.h> | ||||
| 
 | ||||
| #define D3DCLEAR_TARGET  0x1 | ||||
| #define D3DCLEAR_ZBUFFER 0x10 | ||||
|  |  | |||
|  | @ -166,6 +166,9 @@ void UpdateChecker::visitWebsite() | |||
| #elif defined(__linux__) | ||||
|     std::string command = "xdg-open " + std::string(VISIT_URL) + " &"; | ||||
|     std::system(command.c_str()); | ||||
| #elif defined(__APPLE__) | ||||
|     std::string command = "open " + std::string(VISIT_URL) + " &"; | ||||
|     std::system(command.c_str()); | ||||
| #else | ||||
|     static_assert(false, "Visit website not implemented for this platform."); | ||||
| #endif | ||||
|  |  | |||
|  | @ -660,7 +660,7 @@ void KeQueryBasePriorityThread() | |||
| 
 | ||||
| uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount) | ||||
| { | ||||
|     assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->thread.get_id() == std::this_thread::get_id()); | ||||
|     assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId()); | ||||
| 
 | ||||
|     hThread->suspended = true; | ||||
|     hThread->suspended.wait(true); | ||||
|  |  | |||
|  | @ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const | |||
| 
 | ||||
|         if (!exists) | ||||
|         { | ||||
|             std::string root = ""; | ||||
|             std::filesystem::path rootPath; | ||||
| 
 | ||||
|             if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA) | ||||
|             { | ||||
|                 std::u8string savePathU8 = GetSavePath(true).u8string(); | ||||
|                 root = (const char *)(savePathU8.c_str()); | ||||
|                 rootPath = GetSavePath(true); | ||||
|             } | ||||
|             else if (pContentData->dwContentType == XCONTENTTYPE_DLC) | ||||
|             { | ||||
|                 root = GAME_INSTALL_DIRECTORY "/dlc"; | ||||
|                 rootPath = GetGamePath() / "dlc"; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 root = GAME_INSTALL_DIRECTORY; | ||||
|                 rootPath = GetGamePath(); | ||||
|             } | ||||
| 
 | ||||
|             const std::string root = (const char*)rootPath.u8string().c_str(); | ||||
|             XamRegisterContent(*pContentData, root); | ||||
| 
 | ||||
|             std::error_code ec; | ||||
|             std::filesystem::create_directory(std::u8string_view((const char8_t*)(root.c_str())), ec); | ||||
|             std::filesystem::create_directory(rootPath, ec); | ||||
| 
 | ||||
|             XamRootCreate(szRootName, root); | ||||
|         } | ||||
|  |  | |||
|  | @ -123,7 +123,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "ウィンドウサイズ" }, | ||||
|             { ELanguage::German,   "Fenstergröße" }, | ||||
|             { ELanguage::French,   "Taille de la fenêtre" }, | ||||
|             { ELanguage::Spanish,  "Tamaño de ventana" }, | ||||
|             { ELanguage::Spanish,  "Tamaño de la ventana" }, | ||||
|             { ELanguage::Italian,  "Dimensioni della finestra" } | ||||
|         } | ||||
|     }, | ||||
|  | @ -135,7 +135,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "ゲームの\u200Bウィンドウサイズを\u200B[設定:せってい]できます" }, | ||||
|             { ELanguage::German,   "Passe die Fenstergröße des Spiels im Fenstermodus an." }, | ||||
|             { ELanguage::French,   "Définir la résolution de jeu en mode fenêtré." }, | ||||
|             { ELanguage::Spanish,  "Ajusta el tamaño de la ventana de juego en modo ventana." }, | ||||
|             { ELanguage::Spanish,  "Ajusta el tamaño de la ventana del juego en modo ventana." }, | ||||
|             { ELanguage::Italian,  "Regola la dimensione della finestra del gioco in modalità finestra." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -213,7 +213,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "この\u200Bオプションは\u200B[現在:げんざい]の\u200BOSで\u200B[変更:へんこう]\u200Bできません" }, | ||||
|             { ELanguage::German,   "Diese Option wird von diesem Betriebssystem nicht unterstützt." }, | ||||
|             { ELanguage::French,   "Cette option n'est pas prise en charge par votre système d'exploitation." }, | ||||
|             { ELanguage::Spanish,  "Esta opción no está soportada por tu sistema operativo." }, | ||||
|             { ELanguage::Spanish,  "Esta opción no es compatible con tu sistema operativo." }, | ||||
|             { ELanguage::Italian,  "Questa opzione non è disponibile con il tuo sistema operativo." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -226,7 +226,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "ゲームが[再起動:さいきどう]されます" }, | ||||
|             { ELanguage::German,   "Das Spiel wird jetzt neu starten." }, | ||||
|             { ELanguage::French,   "Le jeu va maintenant redémarrer." }, | ||||
|             { ELanguage::Spanish,  "El juego se va a reiniciar." }, | ||||
|             { ELanguage::Spanish,  "El juego se reiniciará." }, | ||||
|             { ELanguage::Italian,  "Il gioco verrà riavviato." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -319,7 +319,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "ゲームのソースとタイトルアップデート\nを[追加:ついか]" }, | ||||
|             { ELanguage::German,   "Füge die Quellen für das Spiel und dessen Update hinzu." }, | ||||
|             { ELanguage::French,   "Ajouter les fichiers du jeu ainsi que ses mises à jour." }, | ||||
|             { ELanguage::Spanish,  "Añade las fuentes para el juego y su actualización." }, | ||||
|             { ELanguage::Spanish,  "Añade los archivos para el juego y su actualización." }, | ||||
|             { ELanguage::Italian,  "Aggiungi le fonti per il gioco e per il suo file d'aggiornamento." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -331,7 +331,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "DLCのソースを[追加:ついか]" }, | ||||
|             { ELanguage::German,   "Füge die Quellen für die Erweiterungen des Spiels hinzu." }, | ||||
|             { ELanguage::French,   "Ajouter les fichiers pour les DLCs." }, | ||||
|             { ELanguage::Spanish,  "Añade las fuentes para el DLC." }, | ||||
|             { ELanguage::Spanish,  "Añade los archivos para el DLC." }, | ||||
|             { ELanguage::Italian,  "Aggiungi le fonti per i DLC." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -343,7 +343,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "コンテンツはプログラムのフォルダに\nインストールされます\n" }, | ||||
|             { ELanguage::German,   "Der Inhalt wird in dem Ordner des Programms installiert.\n" }, | ||||
|             { ELanguage::French,   "Le contenu sera installé dans le même dossier que le programme.\n" }, | ||||
|             { ELanguage::Spanish,  "El contenido será instalado a la carpeta del programa.\n\n" }, | ||||
|             { ELanguage::Spanish,  "El contenido se instalará en la carpeta del programa.\n\n" }, | ||||
|             { ELanguage::Italian,  "Il contenuto verrà installato nella cartella di questo programma.\n\n" } | ||||
|         } | ||||
|     }, | ||||
|  | @ -506,7 +506,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "[提供:ていきょう]されたファイルの[一部:いちぶ]が[有効:ゆうこう]ではありません\n[指定:してい]されたファイルがすべて[正:ただ]しいことを[確認:かくにん]して\nもう[一度:いちど]お[試:ため]しください" }, | ||||
|             { ELanguage::German,   "Einige Dateien, die bereitgestellt\nwurden sind ungültig.\n\nBitte stelle sicher, dass\ndie angegebenen Dateien korrekt\nsind und versuche es erneut." }, | ||||
|             { ELanguage::French,   "Certains fichiers fournis ne\nsont pas valides.\n\nVeuillez vous assurer que tous\nles fichiers spécifiés sont\ncorrects et réessayez." }, | ||||
|             { ELanguage::Spanish,  "Algunos de los archivos\nseleccionados no son válidos.\n\nPor favor, asegúrate de que\ntodos los archivos son correctos\ne inténtalo de nuevo.\n" }, | ||||
|             { ELanguage::Spanish,  "Algunos de los archivos\nseleccionados no son válidos.\n\nPor favor, asegúrate de que\ntodos los archivos sean correctos\ne inténtalo de nuevo.\n" }, | ||||
|             { ELanguage::Italian,  "Alcuni dei file che sono stati\nselezionati non sono validi.\n\nAssicurati che tutti\ni file sono quelli corretti\ne riprova." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -545,7 +545,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "[指定:してい]されたゲームとタイトルアップデートは[互換性:ごかんせい]がありません\n\nファイルのバージョンと[地域:ちいき]が\n[同:おな]じであることを[確認:かくにん]して\nもう[一度:いちど]お[試:ため]しください" }, | ||||
|             { ELanguage::German,   "Die ausgewählten Spiel- und\nUpdatedateien sind inkompatibel.\n\nBitte stelle sicher, dass\ndie Dateien für die selbe\nVersion und Region vorgesehen sind\nund versuche es erneut." }, | ||||
|             { ELanguage::French,   "Les fichiers du jeu et la mise à\njour sont incompatibles.\n\nVeuillez vous assurer que les\nfichiers sont pour la même\nversion/région puis réessayez." }, | ||||
|             { ELanguage::Spanish,  "El juego seleccionado\ny su actualización son incompatibles.\n\nPor favor, asegúrate de que que los archivos\nson de la misma versión y\nregión e inténtalo de nuevo." }, | ||||
|             { ELanguage::Spanish,  "El juego seleccionado\ny su actualización son incompatibles.\n\nPor favor, asegúrate de que los archivos\nsean de la misma versión y\nregión e inténtalo de nuevo." }, | ||||
|             { ELanguage::Italian,  "I file del gioco\ne dell'aggiornamento sono incompatibili.\n\nAssicurati che i file sono\ndella stessa versione\ne regione e riprova." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -558,7 +558,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "ベースゲーム[用:よう]の[高品質:こうひんしつ]の\n[照明:しょうめい]テクスチャが[含:ふく]まれているため\nすべてのDLCをインストールすることを\n[強:つよ]くお[勧:すす]めします\n\nこの[手順:てじゅん]をスキップしてもよろしいですか?" }, | ||||
|             { ELanguage::German,   "Es wird empgohlen alle Erweiterungen zu installieren, da sie Beleuchtungs-Texturen in einer höheren Qualität für das Basisspiel beinhalten.\n\nBist du dir sicher, dass du diesen Schritt überspringen möchtest?" }, | ||||
|             { ELanguage::French,   "Il est fortement recommandé\nd'installer l'ensemble du\nDLC car elle inclut des\ntextures de lumière de\nhaute qualité pour le jeu\nde base.\n\nÊtes-vous sûr de vouloir\nignorer cette étape ?" }, | ||||
|             { ELanguage::Spanish,  "Se recomienda encarecidamente\ninstalar todo el DLC, ya que\ncontiene texturas de iluminación\nde alta calidad para el juego base.\n\n¿Seguro que quieres saltar este paso?" }, | ||||
|             { ELanguage::Spanish,  "Se recomienda encarecidamente\ninstalar todo el DLC, ya que\nincluye texturas de iluminación\nde alta calidad para el juego base.\n\n¿Estás seguro de que quieres\nomitir este paso?" }, | ||||
|             { ELanguage::Italian,  "Si consiglia di installare\ntutti i DLC, poichè includono\ntexture di illuminazione di qualità migliore.\n\nSei sicuro di voler saltare?" } | ||||
|         } | ||||
|     }, | ||||
|  | @ -584,7 +584,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "これによりゲームが[再起動:さいきどう]され\n[不足:ふそく]しているDLCを\nインストールできるようになります\n\n[現在:げんざい] [不足:ふそく]しているDLCはありません\n\nそれでも[続行:ぞっこう]しますか?" }, | ||||
|             { ELanguage::German,   "Das Spiel wird neu gestartet\num die Installation einer fehlenden\nErweiterung zu ermöglichen.\n\nEs kann keine weitere Erweiterung\ninstalliert werden.\n\nMöchtest du trotzdem fortfahren?" }, | ||||
|             { ELanguage::French,   "Cela redémarrera le jeu pour vous\npermettre d'installer les DLC\nmanquants.\n\nIl ne vous manque aucun DLC.\n\nVoulez-vous quand même continuer ?" }, | ||||
|             { ELanguage::Spanish,  "Esto reiniciará el juego\npara permitirte instalar\nlos DLC que falten.\n\nActualmente, no falta ningún\nDLC por instalarse.\n\n¿Quieres continuar de todos\nmodos?" }, | ||||
|             { ELanguage::Spanish,  "Esto reiniciará el juego\npara permitirte instalar\nlos DLC que falten.\n\nActualmente, no falta ningún\nDLC por instalar.\n\n¿Quieres continuar de todos\nmodos?" }, | ||||
|             { ELanguage::Italian,  "Questa opzione riavviera il gioco\nper farti installare qualsiasi DLC\nche non hai installato.\n\nHai già installato tutti i DLC.\n\nVuoi procedere comunque?" } | ||||
|         } | ||||
|     }, | ||||
|  | @ -665,7 +665,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "[実績:じっせき]データを[読:よ]み[込:こ]めませんでした\n[実績:じっせき]は[保存:ほぞん]されません。" }, | ||||
|             { ELanguage::German,   "Die Erfolgsdaten konnten nicht geladen werden.\nDeine Erfolge werden nicht gespeichert." }, | ||||
|             { ELanguage::French,   "Les données des succès ne\npeuvent être chargées.\nVos succès ne seront pas\nsauvegardés." }, | ||||
|             { ELanguage::Spanish,  "Los datos de logros no pueden cargarse.\nTus logros no serán guardados." }, | ||||
|             { ELanguage::Spanish,  "Los datos de logros no pueden cargarse.\nTus logros no se guardarán." }, | ||||
|             { ELanguage::Italian,  "I file degli obiettivi non possono essere caricati.\nI tuoi obiettivi non verranno salvati." } | ||||
|         } | ||||
|     }, | ||||
|  | @ -677,7 +677,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "アップデートが[利用:りよう][可能:かのう]です\n\nリリースページにアクセスして\nダウンロードしますか?" }, | ||||
|             { ELanguage::German,   "Ein Update ist verfügbar!\n\nMöchtest du die Release-Seite\nbesuchen um es herunterzuladen?" }, | ||||
|             { ELanguage::French,   "Une mise à jour est disponible !\n\nVoulez-vous visiter la page\ndes mises à jour pour la\ntélécharger ?" }, | ||||
|             { ELanguage::Spanish,  "¡Hay una actualización disponible!\n\n¿Quieres ir a la página\npara descargarla?" }, | ||||
|             { ELanguage::Spanish,  "¡Hay una actualización disponible!\n\n¿Quieres ir a la página de\nlanzamientos para descargarla?" }, | ||||
|             { ELanguage::Italian,  "È disponibile un aggiornamento!\n\nVuoi visitare la pagina releases\nper scaricarlo?" } | ||||
|         } | ||||
|     }, | ||||
|  | @ -688,7 +688,7 @@ std::unordered_map<std::string_view, std::unordered_map<ELanguage, std::string>> | |||
|             { ELanguage::Japanese, "D3D12 (Windows)または\nVulkanバックエンドを作成できません\n\n次の点を確認してください:\n\n※システムが最小要件を満たしている\n※GPUドライバーが最新である\n※オペレーティングシステムが最新バージョンである" }, | ||||
|             { ELanguage::German,   "Es ist nicht möglich, ein D3D12 (Windows) oder Vulkan-Backend zu erstellen.\n\nBitte stelle sicher, dass:\n\n- Dein System die Mindestanforderungen erfüllt.\n- Deine GPU-Treiber auf dem neuesten Stand sind.\n- Dein Betriebssystem auf der neuesten verfügbaren Version ist." }, | ||||
|             { ELanguage::French,   "Impossible de créer un backend D3D12 (Windows) ou Vulkan.\n\nVeuillez vous assurer que :\n\n- Votre système répond aux critères minimums requis.\n- Les pilotes de votre processeur graphique sont à jour.\n- Votre système d'exploitation est à jour." }, | ||||
|             { ELanguage::Spanish,  "No se puede crear un entorno de D3D12 (Windows) o de Vulkan.\n\nPor favor, asegúrate de que:\n\n- Tu equipo cumple con los requisitos mínimos.\n- Los drivers de tu tarjeta gráfica están actualizados.\n- Tu sistema operativo está actualizado a la última versión.\n" }, | ||||
|             { ELanguage::Spanish,  "No se puede crear un backend D3D12 (Windows) ni un backend Vulkan.\n\nAsegúrate de que:\n\n- Tu equipo cumple con los requisitos mínimos.\n- Los controladores de tu tarjeta gráfica están actualizados.\n- Tu sistema operativo está actualizado a la última versión.\n" }, | ||||
|             { ELanguage::Italian,  "Impossibile creare un backend D3D12 (Windows) o Vulkan.\n\nAssicurati che:\n\n- Il tuo sistema soddisfi i requisiti minimi.\n- I driver della scheda grafica siano aggiornati.\n- Il tuo sistema operativo sia aggiornato." } | ||||
|         } | ||||
|     }, | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| #include <stdafx.h> | ||||
| #ifdef __x86_64__ | ||||
| #include <cpuid.h> | ||||
| #endif | ||||
| #include <cpu/guest_thread.h> | ||||
| #include <gpu/video.h> | ||||
| #include <kernel/function.h> | ||||
|  | @ -69,8 +71,10 @@ void KiSystemStartup() | |||
| 
 | ||||
|     const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game"); | ||||
|     const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update"); | ||||
|     XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game"); | ||||
|     XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update"); | ||||
|     const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str(); | ||||
|     const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str(); | ||||
|     XamRegisterContent(gameContent, gamePath); | ||||
|     XamRegisterContent(updateContent, updatePath); | ||||
| 
 | ||||
|     const auto saveFilePath = GetSaveFilePath(true); | ||||
|     bool saveFileExists = std::filesystem::exists(saveFilePath); | ||||
|  | @ -102,7 +106,7 @@ void KiSystemStartup() | |||
|     XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr); | ||||
| 
 | ||||
|     std::error_code ec; | ||||
|     for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec)) | ||||
|     for (auto& file : std::filesystem::directory_iterator(GetGamePath() / "dlc", ec)) | ||||
|     { | ||||
|         if (file.is_directory()) | ||||
|         { | ||||
|  | @ -165,10 +169,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path) | |||
|     return entry; | ||||
| } | ||||
| 
 | ||||
| #ifdef __x86_64__ | ||||
| __attribute__((constructor(101), target("no-avx,no-avx2"), noinline)) | ||||
| void init() | ||||
| { | ||||
| #ifdef __x86_64__ | ||||
|     uint32_t eax, ebx, ecx, edx; | ||||
| 
 | ||||
|     // Execute CPUID for processor info and feature bits.
 | ||||
|  | @ -185,8 +189,8 @@ void init() | |||
| 
 | ||||
|         std::_Exit(1); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
|  | @ -232,7 +236,7 @@ int main(int argc, char *argv[]) | |||
|     { | ||||
|         // Set the current working directory to the executable's path.
 | ||||
|         std::error_code ec; | ||||
|         std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec); | ||||
|         std::filesystem::current_path(os::process::GetExecutableRoot(), ec); | ||||
|     } | ||||
| 
 | ||||
|     Config::Load(); | ||||
|  | @ -321,7 +325,7 @@ int main(int argc, char *argv[]) | |||
|     HostStartup(); | ||||
| 
 | ||||
|     std::filesystem::path modulePath; | ||||
|     bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath); | ||||
|     bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath); | ||||
|     bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled; | ||||
|     if (runInstallerWizard) | ||||
|     { | ||||
|  | @ -331,7 +335,7 @@ int main(int argc, char *argv[]) | |||
|             std::_Exit(1); | ||||
|         } | ||||
| 
 | ||||
|         if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller)) | ||||
|         if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller)) | ||||
|         { | ||||
|             std::_Exit(0); | ||||
|         } | ||||
|  |  | |||
|  | @ -100,7 +100,7 @@ void ModLoader::Init() | |||
|     { | ||||
|         configIni = {}; | ||||
| 
 | ||||
|         if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini")) | ||||
|         if (!configIni.read(GetGamePath() / "cpkredir.ini")) | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,11 @@ std::filesystem::path os::process::GetExecutablePath() | |||
|     } | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     return GetExecutablePath().remove_filename(); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetWorkingDirectory() | ||||
| { | ||||
|     char cwd[PATH_MAX] = {}; | ||||
|  |  | |||
							
								
								
									
										17
									
								
								UnleashedRecomp/os/macos/logger_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								UnleashedRecomp/os/macos/logger_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| #include <os/logger.h> | ||||
| 
 | ||||
| void os::logger::Init() | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void os::logger::Log(const std::string_view str, ELogType type, const char* func) | ||||
| { | ||||
|     if (func) | ||||
|     { | ||||
|         fmt::println("[{}] {}", func, str); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         fmt::println("{}", str); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								UnleashedRecomp/os/macos/media_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								UnleashedRecomp/os/macos/media_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #include <os/media.h> | ||||
| 
 | ||||
| bool os::media::IsExternalMediaPlaying() | ||||
| { | ||||
|     // This functionality is not supported in macOS.
 | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										97
									
								
								UnleashedRecomp/os/macos/process_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								UnleashedRecomp/os/macos/process_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,97 @@ | |||
| #include <os/process.h> | ||||
| 
 | ||||
| #include <CoreFoundation/CFBundle.h> | ||||
| #include <dlfcn.h> | ||||
| #include <mach-o/dyld.h> | ||||
| #include <signal.h> | ||||
| #include <sys/param.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutablePath() | ||||
| { | ||||
|     uint32_t exePathSize = PATH_MAX; | ||||
|     char exePath[PATH_MAX] = {}; | ||||
|     if (_NSGetExecutablePath(exePath, &exePathSize) == 0) | ||||
|     { | ||||
|         return std::filesystem::path(std::u8string_view((const char8_t*)(exePath))); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return std::filesystem::path(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     std::filesystem::path resultPath = GetExecutablePath().remove_filename(); | ||||
|     if (CFBundleRef bundleRef = CFBundleGetMainBundle()) | ||||
|     { | ||||
|         if (CFURLRef bundleUrlRef = CFBundleCopyBundleURL(bundleRef)) | ||||
|         { | ||||
|             char appBundlePath[MAXPATHLEN]; | ||||
|             if (CFURLGetFileSystemRepresentation(bundleUrlRef, true, (uint8_t*)(appBundlePath), sizeof(appBundlePath))) | ||||
|             { | ||||
|                 resultPath = std::filesystem::path(appBundlePath).parent_path(); | ||||
|             } | ||||
|             CFRelease(bundleUrlRef); | ||||
|         } | ||||
|     } | ||||
|     return resultPath; | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetWorkingDirectory() | ||||
| { | ||||
|     char cwd[PATH_MAX] = {}; | ||||
|     char *res = getcwd(cwd, sizeof(cwd)); | ||||
|     if (res != nullptr) | ||||
|     { | ||||
|         return std::filesystem::path(std::u8string_view((const char8_t*)(cwd))); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         return std::filesystem::path(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| bool os::process::SetWorkingDirectory(const std::filesystem::path& path) | ||||
| { | ||||
|     return chdir(path.c_str()) == 0; | ||||
| } | ||||
| 
 | ||||
| bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work) | ||||
| { | ||||
|     pid_t pid = fork(); | ||||
|     if (pid < 0) | ||||
|         return false; | ||||
| 
 | ||||
|     if (pid == 0) | ||||
|     { | ||||
|         setsid(); | ||||
| 
 | ||||
|         std::u8string workU8 = work.u8string(); | ||||
|         chdir((const char*)(workU8.c_str())); | ||||
| 
 | ||||
|         std::u8string pathU8 = path.u8string(); | ||||
|         std::vector<char*> argStrs; | ||||
|         argStrs.push_back((char*)(pathU8.c_str())); | ||||
|         for (const std::string& arg : args) | ||||
|             argStrs.push_back((char *)(arg.c_str())); | ||||
| 
 | ||||
|         argStrs.push_back(nullptr); | ||||
|         execvp((const char*)(pathU8.c_str()), argStrs.data()); | ||||
|         raise(SIGKILL); | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void os::process::CheckConsole() | ||||
| { | ||||
|     // Always visible on macOS.
 | ||||
|     g_consoleVisible = true; | ||||
| } | ||||
| 
 | ||||
| void os::process::ShowConsole() | ||||
| { | ||||
|     // Unnecessary on macOS.
 | ||||
| } | ||||
							
								
								
									
										21
									
								
								UnleashedRecomp/os/macos/registry_macos.inl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								UnleashedRecomp/os/macos/registry_macos.inl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| #include <os/registry.h> | ||||
| 
 | ||||
| // TODO: Implement | ||||
| inline bool os::registry::Init() | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // TODO: read from file? | ||||
| template<typename T> | ||||
| bool os::registry::ReadValue(const std::string_view& name, T& data) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // TODO: write to file? | ||||
| template<typename T> | ||||
| bool os::registry::WriteValue(const std::string_view& name, const T& data) | ||||
| { | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										6
									
								
								UnleashedRecomp/os/macos/user_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								UnleashedRecomp/os/macos/user_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| #include <os/user.h> | ||||
| 
 | ||||
| bool os::user::IsDarkTheme() | ||||
| { | ||||
|     return false; | ||||
| } | ||||
							
								
								
									
										7
									
								
								UnleashedRecomp/os/macos/version_macos.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								UnleashedRecomp/os/macos/version_macos.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| #include <os/version.h> | ||||
| 
 | ||||
| os::version::OSVersion os::version::GetOSVersion() | ||||
| { | ||||
|     assert(false && "Unimplemented."); | ||||
|     return os::version::OSVersion(); | ||||
| } | ||||
|  | @ -5,6 +5,7 @@ namespace os::process | |||
|     inline bool g_consoleVisible; | ||||
| 
 | ||||
|     std::filesystem::path GetExecutablePath(); | ||||
|     std::filesystem::path GetExecutableRoot(); | ||||
|     std::filesystem::path GetWorkingDirectory(); | ||||
|     bool SetWorkingDirectory(const std::filesystem::path& path); | ||||
|     bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {}); | ||||
|  |  | |||
|  | @ -15,4 +15,6 @@ namespace os::registry | |||
| #include <os/win32/registry_win32.inl> | ||||
| #elif defined(__linux__) | ||||
| #include <os/linux/registry_linux.inl> | ||||
| #elif defined(__APPLE__) | ||||
| #include <os/macos/registry_macos.inl> | ||||
| #endif | ||||
|  |  | |||
|  | @ -10,6 +10,11 @@ std::filesystem::path os::process::GetExecutablePath() | |||
|     return std::filesystem::path(exePath); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetExecutableRoot() | ||||
| { | ||||
|     return GetExecutablePath().remove_filename(); | ||||
| } | ||||
| 
 | ||||
| std::filesystem::path os::process::GetWorkingDirectory() | ||||
| { | ||||
|     WCHAR workPath[MAX_PATH]; | ||||
|  |  | |||
							
								
								
									
										42
									
								
								UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||||
| <plist version="1.0"> | ||||
| <dict> | ||||
| 	<key>CFBundleDevelopmentRegion</key> | ||||
| 	<string>English</string> | ||||
| 	<key>CFBundleExecutable</key> | ||||
| 	<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> | ||||
| 	<key>CFBundleGetInfoString</key> | ||||
| 	<string>${MACOSX_BUNDLE_INFO_STRING}</string> | ||||
| 	<key>CFBundleIconFile</key> | ||||
| 	<string>${MACOSX_BUNDLE_ICON_FILE}</string> | ||||
| 	<key>CFBundleIdentifier</key> | ||||
| 	<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> | ||||
| 	<key>CFBundleInfoDictionaryVersion</key> | ||||
| 	<string>6.0</string> | ||||
| 	<key>CFBundleLongVersionString</key> | ||||
| 	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> | ||||
| 	<key>CFBundleName</key> | ||||
| 	<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> | ||||
| 	<key>CFBundlePackageType</key> | ||||
| 	<string>APPL</string> | ||||
| 	<key>CFBundleShortVersionString</key> | ||||
| 	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> | ||||
| 	<key>CFBundleSignature</key> | ||||
| 	<string>????</string> | ||||
| 	<key>CFBundleVersion</key> | ||||
| 	<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> | ||||
| 	<key>CSResourcesFileMapped</key> | ||||
| 	<true/> | ||||
| 	<key>NSHumanReadableCopyright</key> | ||||
| 	<string>${MACOSX_BUNDLE_COPYRIGHT}</string> | ||||
| 	<key>LSMinimumSystemVersion</key> | ||||
| 	<string>13.0</string> | ||||
| 	<key>LSApplicationCategoryType</key> | ||||
| 	<string>public.app-category.games</string> | ||||
| 	<key>GCSupportsGameMode</key> | ||||
| 	<true/> | ||||
| 	<key>NSHighResolutionCapable</key> | ||||
| 	<true/> | ||||
| </dict> | ||||
| </plist> | ||||
							
								
								
									
										
											BIN
										
									
								
								UnleashedRecomp/res/macos/game_icon.icns
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								UnleashedRecomp/res/macos/game_icon.icns
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							|  | @ -20,7 +20,7 @@ std::unique_ptr<GuestTexture> g_upKBMIcons; | |||
| 
 | ||||
| float g_sideMargins = DEFAULT_SIDE_MARGINS; | ||||
| 
 | ||||
| std::vector<Button> g_buttons; | ||||
| static std::vector<Button> g_buttons; | ||||
| 
 | ||||
| std::unordered_map<EButtonIcon, float> g_iconWidths = | ||||
| { | ||||
|  |  | |||
|  | @ -217,6 +217,9 @@ void GameWindow::Init(const char* sdlVideoDriver) | |||
|     s_renderWindow = s_pWindow; | ||||
| #elif defined(__linux__) | ||||
|     s_renderWindow = { info.info.x11.display, info.info.x11.window }; | ||||
| #elif defined(__APPLE__) | ||||
|     s_renderWindow.window = info.info.cocoa.window; | ||||
|     s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow)); | ||||
| #else | ||||
|     static_assert(false, "Unknown platform."); | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <gpu/rhi/plume_render_interface_types.h> | ||||
| #include <plume_render_interface_types.h> | ||||
| #include <user/config.h> | ||||
| #include <sdl_events.h> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1146,7 +1146,11 @@ static void PickerStart(bool folderMode) { | |||
|     g_currentPickerVisible = true; | ||||
| 
 | ||||
|     // Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
 | ||||
| #ifdef __APPLE__ | ||||
|     constexpr bool singleThreadMode = true; | ||||
| #else | ||||
|     constexpr bool singleThreadMode = false; | ||||
| #endif | ||||
|     if (singleThreadMode) | ||||
|         PickerThreadProcess(); | ||||
|     else | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ static ImFont* g_fntSeurat; | |||
| 
 | ||||
| std::string g_text; | ||||
| int g_result; | ||||
| std::vector<std::string> g_buttons; | ||||
| static std::vector<std::string> g_buttons; | ||||
| int g_defaultButtonIndex; | ||||
| int g_cancelButtonIndex; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| #include "paths.h" | ||||
| #include <os/process.h> | ||||
| 
 | ||||
| std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename(); | ||||
| std::filesystem::path g_executableRoot = os::process::GetExecutableRoot(); | ||||
| std::filesystem::path g_userPath = BuildUserPath(); | ||||
| 
 | ||||
| bool CheckPortable() | ||||
|  | @ -22,18 +22,24 @@ std::filesystem::path BuildUserPath() | |||
|         userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; | ||||
| 
 | ||||
|     CoTaskMemFree(knownPath); | ||||
| #elif defined(__linux__) | ||||
| #elif defined(__linux__) || defined(__APPLE__) | ||||
|     const char* homeDir = getenv("HOME"); | ||||
| #if defined(__linux__) | ||||
|     if (homeDir == nullptr) | ||||
|     { | ||||
|         homeDir = getpwuid(getuid())->pw_dir; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     if (homeDir != nullptr) | ||||
|     { | ||||
|         // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 | ||||
|         std::filesystem::path homePath = homeDir; | ||||
| #if defined(__linux__) | ||||
|         std::filesystem::path configPath = homePath / ".config"; | ||||
| #else | ||||
|         std::filesystem::path configPath = homePath / "Library" / "Application Support"; | ||||
| #endif | ||||
|         if (std::filesystem::exists(configPath)) | ||||
|             userPath = configPath / USER_DIRECTORY; | ||||
|         else | ||||
|  |  | |||
|  | @ -10,15 +10,22 @@ | |||
| 
 | ||||
| extern std::filesystem::path g_executableRoot; | ||||
| 
 | ||||
| inline std::filesystem::path GetGamePath() | ||||
| { | ||||
|     return GAME_INSTALL_DIRECTORY; | ||||
| } | ||||
| 
 | ||||
| bool CheckPortable(); | ||||
| std::filesystem::path BuildUserPath(); | ||||
| const std::filesystem::path& GetUserPath(); | ||||
| 
 | ||||
| inline std::filesystem::path GetGamePath() | ||||
| { | ||||
| #ifdef __APPLE__ | ||||
|     // On macOS, there is the expectation that the app may be installed to
 | ||||
|     // /Applications/, and the bundle should not be modified. Thus we need
 | ||||
|     // to install game files to the user directory instead of next to the app.
 | ||||
|     return GetUserPath(); | ||||
| #else | ||||
|     return GAME_INSTALL_DIRECTORY; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| inline std::filesystem::path GetSavePath(bool checkForMods) | ||||
| { | ||||
|     if (checkForMods && !ModLoader::s_saveFilePath.empty()) | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ add_custom_command( | |||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex" | ||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp" | ||||
|         "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml" | ||||
|     USES_TERMINAL | ||||
| ) | ||||
| 
 | ||||
| add_custom_command( | ||||
|  | @ -53,6 +54,7 @@ target_compile_definitions(XenosRecomp PRIVATE | |||
|     XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"  | ||||
|     XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\" | ||||
|     XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\" | ||||
|     UNLEASHED_RECOMP | ||||
| ) | ||||
| 
 | ||||
| file(GLOB XENOS_RECOMP_SOURCES  | ||||
|  | @ -70,6 +72,7 @@ add_custom_command( | |||
|         "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"  | ||||
|         ${XENOS_RECOMP_SOURCES}  | ||||
|         ${XENOS_RECOMP_INCLUDE} | ||||
|     USES_TERMINAL | ||||
| ) | ||||
| 
 | ||||
| add_library(UnleashedRecompLib  | ||||
|  | @ -79,4 +82,5 @@ add_library(UnleashedRecompLib | |||
| ) | ||||
| 
 | ||||
| target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) | ||||
| target_include_directories(UnleashedRecompLib PRIVATE "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenonRecomp/thirdparty/simde") | ||||
| target_precompile_headers(UnleashedRecompLib PUBLIC "ppc/ppc_recomp_shared.h") | ||||
|  |  | |||
|  | @ -50,6 +50,21 @@ You can also find the equivalent packages for your preferred distro. | |||
| > [!NOTE] | ||||
| > This list may not be comprehensive for your particular distro and you may be required to install additional packages, should an error occur during configuration. | ||||
| 
 | ||||
| ### macOS | ||||
| You will need to install Xcode 16.3+ or the equivalent Xcode Command Line Tools from Apple. | ||||
| 
 | ||||
| The following commands will install additional required dependencies, depending on which package manager you use. | ||||
| 
 | ||||
| If you use Homebrew: | ||||
| ```bash | ||||
| brew install cmake ninja pkg-config | ||||
| ``` | ||||
| 
 | ||||
| If you use MacPorts: | ||||
| ```bash | ||||
| sudo port install cmake ninja pkg-config | ||||
| ``` | ||||
| 
 | ||||
| ## 4. Build the Project | ||||
| 
 | ||||
| ### Windows | ||||
|  | @ -81,3 +96,22 @@ cmake --build ./out/build/linux-release --target UnleashedRecomp | |||
| ```bash | ||||
| ./UnleashedRecomp | ||||
| ``` | ||||
| 
 | ||||
| ### macOS | ||||
| 1. Configure the project using CMake by navigating to the repository and running the following command. | ||||
| ```bash | ||||
| cmake . --preset macos-release | ||||
| ``` | ||||
| 
 | ||||
| > [!NOTE] | ||||
| > The available presets are `macos-debug`, `macos-relwithdebinfo` and `macos-release`. | ||||
| 
 | ||||
| 2. Build the project using the selected configuration. | ||||
| ```bash | ||||
| cmake --build ./out/build/macos-release --target UnleashedRecomp | ||||
| ``` | ||||
| 
 | ||||
| 3. Navigate to the directory that was specified as the output in the previous step and run the game. | ||||
| ```bash | ||||
| open -a UnleashedRecomp.app | ||||
| ``` | ||||
|  |  | |||
							
								
								
									
										13
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -15,8 +15,21 @@ set(SDL2MIXER_OPUS OFF) | |||
| set(SDL2MIXER_VORBIS "VORBISFILE") | ||||
| set(SDL2MIXER_WAVPACK OFF) | ||||
| 
 | ||||
| if (CMAKE_SYSTEM_NAME MATCHES "Linux") | ||||
|     set(SDL_VULKAN_ENABLED ON CACHE BOOL "") | ||||
| endif() | ||||
| 
 | ||||
| if (WIN32) | ||||
|     set(D3D12_AGILITY_SDK_ENABLED ON CACHE BOOL "") | ||||
| endif() | ||||
| 
 | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/msdf-atlas-gen") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer") | ||||
| add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume") | ||||
| 
 | ||||
| if (APPLE) | ||||
|     add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK") | ||||
| endif() | ||||
|  |  | |||
							
								
								
									
										1
									
								
								thirdparty/D3D12MemoryAllocator
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/D3D12MemoryAllocator
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f | ||||
							
								
								
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | |||
| # Simple CMake script to compile MoltenVK with SPIRV-Cross as a shared library target | ||||
| 
 | ||||
| # Prepare MoltenVK Git revision | ||||
| find_package(Git) | ||||
| if(GIT_FOUND) | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD | ||||
|             OUTPUT_VARIABLE MVK_GIT_REV | ||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK | ||||
|             ERROR_QUIET | ||||
|             OUTPUT_STRIP_TRAILING_WHITESPACE) | ||||
| endif() | ||||
| set(MVK_GENERATED_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/Generated) | ||||
| file(WRITE ${MVK_GENERATED_INCLUDES}/mvkGitRevDerived.h "static const char* mvkRevString = \"${MVK_GIT_REV}\";") | ||||
| message(STATUS "MoltenVK revision: ${MVK_GIT_REV}") | ||||
| 
 | ||||
| # Prepare MoltenVK version | ||||
| file(READ ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/MoltenVK/API/mvk_private_api.h MVK_PRIVATE_API) | ||||
| string(REGEX MATCH "#define MVK_VERSION_MAJOR   [0-9]+" MVK_VERSION_MAJOR_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_MAJOR "${MVK_VERSION_MAJOR_LINE}") | ||||
| string(REGEX MATCH "#define MVK_VERSION_MINOR   [0-9]+" MVK_VERSION_MINOR_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_MINOR "${MVK_VERSION_MINOR_LINE}") | ||||
| string(REGEX MATCH "#define MVK_VERSION_PATCH   [0-9]+" MVK_VERSION_PATCH_LINE "${MVK_PRIVATE_API}") | ||||
| string(REGEX MATCH "[0-9]+" MVK_VERSION_PATCH "${MVK_VERSION_PATCH_LINE}") | ||||
| set(MVK_VERSION "${MVK_VERSION_MAJOR}.${MVK_VERSION_MINOR}.${MVK_VERSION_PATCH}") | ||||
| message(STATUS "MoltenVK version: ${MVK_VERSION}") | ||||
| 
 | ||||
| # Find required system libraries | ||||
| find_library(APPKIT_LIBRARY AppKit REQUIRED) | ||||
| find_library(FOUNDATION_LIBRARY Foundation REQUIRED) | ||||
| find_library(IOKIT_LIBRARY IOKit REQUIRED) | ||||
| find_library(IOSURFACE_LIBRARY IOSurface REQUIRED) | ||||
| find_library(METAL_LIBRARY Metal REQUIRED) | ||||
| find_library(QUARTZCORE_LIBRARY QuartzCore REQUIRED) | ||||
| 
 | ||||
| # SPIRV-Cross | ||||
| option(SPIRV_CROSS_CLI "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_TESTS "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_HLSL "" OFF) | ||||
| option(SPIRV_CROSS_ENABLE_CPP "" OFF) | ||||
| option(SPIRV_CROSS_SKIP_INSTALL "" ON) | ||||
| add_subdirectory(SPIRV-Cross) | ||||
| 
 | ||||
| # Common | ||||
| set(MVK_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Common) | ||||
| file(GLOB_RECURSE MVK_COMMON_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_COMMON_DIR}/*.cpp | ||||
|     ${MVK_COMMON_DIR}/*.m | ||||
|     ${MVK_COMMON_DIR}/*.mm) | ||||
| set(MVK_COMMON_INCLUDES ${MVK_COMMON_DIR}) | ||||
| 
 | ||||
| add_library(MoltenVKCommon STATIC ${MVK_COMMON_SOURCES}) | ||||
| target_include_directories(MoltenVKCommon PUBLIC ${MVK_COMMON_INCLUDES}) | ||||
| target_compile_options(MoltenVKCommon PRIVATE -w) | ||||
| 
 | ||||
| # MoltenVKShaderConverter | ||||
| set(MVK_SHADER_CONVERTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKShaderConverter) | ||||
| file(GLOB_RECURSE MVK_SHADER_CONVERTER_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.cpp | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.m | ||||
|     ${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.mm) | ||||
| set(MVK_SHADER_CONVERTER_INCLUDES ${MVK_SHADER_CONVERTER_DIR} ${MVK_SHADER_CONVERTER_DIR}/include) | ||||
| 
 | ||||
| add_library(MoltenVKShaderConverter STATIC ${MVK_SHADER_CONVERTER_SOURCES}) | ||||
| target_include_directories(MoltenVKShaderConverter PUBLIC ${MVK_SHADER_CONVERTER_INCLUDES}) | ||||
| target_compile_options(MoltenVKShaderConverter PRIVATE -w) | ||||
| target_link_libraries(MoltenVKShaderConverter PRIVATE spirv-cross-msl spirv-cross-reflect MoltenVKCommon) | ||||
| target_compile_definitions(MoltenVKShaderConverter PRIVATE MVK_EXCLUDE_SPIRV_TOOLS=1) | ||||
| 
 | ||||
| # MoltenVK | ||||
| set(MVK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK) | ||||
| file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS | ||||
|     ${MVK_DIR}/MoltenVK/*.cpp | ||||
|     ${MVK_DIR}/MoltenVK/*.m | ||||
|     ${MVK_DIR}/MoltenVK/*.mm) | ||||
| file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*) | ||||
| set(MVK_INCLUDES | ||||
|     ${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include | ||||
|     ${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume/contrib/Vulkan-Headers/include) | ||||
| 
 | ||||
| add_library(MoltenVK SHARED ${MVK_SOURCES}) | ||||
| target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES}) | ||||
| target_compile_options(MoltenVK PRIVATE -w) | ||||
| target_link_libraries(MoltenVK PRIVATE | ||||
|     ${APPKIT_LIBRARY} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY} | ||||
|     spirv-cross-msl MoltenVKCommon MoltenVKShaderConverter) | ||||
| target_compile_definitions(MoltenVK PRIVATE MVK_FRAMEWORK_VERSION=${MVK_VERSION} MVK_USE_CEREAL=0) | ||||
							
								
								
									
										1
									
								
								thirdparty/MoltenVK/MoltenVK
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/MoltenVK
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 3a0b07a24a4a681ffe70b461b1f4333b2729e2ef | ||||
							
								
								
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 22b22f5685d868828be01c9ac00c31902e60afd9 | ||||
							
								
								
									
										1
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7 | ||||
							
								
								
									
										1
									
								
								thirdparty/VulkanMemoryAllocator
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/VulkanMemoryAllocator
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39 | ||||
							
								
								
									
										1
									
								
								thirdparty/plume
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/plume
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 11926860e878e68626ea99ec88562ce2b8badc4f | ||||
							
								
								
									
										1
									
								
								thirdparty/volk
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/volk
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit c017eb630ab917bffd3bc6a0a46995b49e7d8049 | ||||
| Subproject commit c5bfd90d87f2ed0db8cff5c19ea3aff0e161e527 | ||||
|  | @ -1 +1 @@ | |||
| Subproject commit 56738e5893ed7c4dc108996590475c52726623e3 | ||||
| Subproject commit 990d03b28a27b50277ee5d8d942e1c5f873869d1 | ||||
|  | @ -9,8 +9,12 @@ | |||
|             "name": "directx12-agility", | ||||
|             "platform": "windows" | ||||
|         }, | ||||
|         "directx-dxc", | ||||
|         "freetype", | ||||
|         "curl" | ||||
|     ] | ||||
|     ], | ||||
|     "vcpkg-configuration": { | ||||
|         "overlay-triplets": [ | ||||
|             "vcpkg/triplets" | ||||
|         ] | ||||
|     } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										7
									
								
								vcpkg/triplets/arm64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vcpkg/triplets/arm64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| set(VCPKG_TARGET_ARCHITECTURE arm64) | ||||
| set(VCPKG_CRT_LINKAGE dynamic) | ||||
| set(VCPKG_LIBRARY_LINKAGE static) | ||||
| 
 | ||||
| set(VCPKG_CMAKE_SYSTEM_NAME Darwin) | ||||
| set(VCPKG_OSX_ARCHITECTURES arm64) | ||||
| set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0") | ||||
							
								
								
									
										7
									
								
								vcpkg/triplets/x64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vcpkg/triplets/x64-osx.cmake
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| set(VCPKG_TARGET_ARCHITECTURE x64) | ||||
| set(VCPKG_CRT_LINKAGE dynamic) | ||||
| set(VCPKG_LIBRARY_LINKAGE static) | ||||
| 
 | ||||
| set(VCPKG_CMAKE_SYSTEM_NAME Darwin) | ||||
| set(VCPKG_OSX_ARCHITECTURES x86_64) | ||||
| set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0") | ||||
		Loading…
	
	Add table
		
		Reference in a new issue