mirror of
				https://github.com/hedge-dev/UnleashedRecomp.git
				synced 2025-10-30 07:11:05 +00:00 
			
		
		
		
	Compare commits
	
		
			1 commit
		
	
	
		
			2fad39e730
			...
			02246fc9ae
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						02246fc9ae | 
					 57 changed files with 11830 additions and 831 deletions
				
			
		
							
								
								
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								.github/workflows/validate.yml
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -210,80 +210,3 @@ jobs:
 | 
				
			||||||
        with:
 | 
					        with:
 | 
				
			||||||
          name: UnleashedRecomp-Flatpak
 | 
					          name: UnleashedRecomp-Flatpak
 | 
				
			||||||
          path: ./${{ env.FLATPAK_ID }}.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,9 +16,21 @@
 | 
				
			||||||
[submodule "thirdparty/vcpkg"]
 | 
					[submodule "thirdparty/vcpkg"]
 | 
				
			||||||
	path = thirdparty/vcpkg
 | 
						path = thirdparty/vcpkg
 | 
				
			||||||
	url = https://github.com/microsoft/vcpkg
 | 
						url = https://github.com/microsoft/vcpkg
 | 
				
			||||||
 | 
					[submodule "thirdparty/volk"]
 | 
				
			||||||
 | 
						path = thirdparty/volk
 | 
				
			||||||
 | 
						url = https://github.com/zeux/volk
 | 
				
			||||||
[submodule "thirdparty/SDL"]
 | 
					[submodule "thirdparty/SDL"]
 | 
				
			||||||
	path = thirdparty/SDL
 | 
						path = thirdparty/SDL
 | 
				
			||||||
	url = https://github.com/libsdl-org/SDL.git
 | 
						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"]
 | 
					[submodule "thirdparty/stb"]
 | 
				
			||||||
	path = thirdparty/stb
 | 
						path = thirdparty/stb
 | 
				
			||||||
	url = https://github.com/nothings/stb.git
 | 
						url = https://github.com/nothings/stb.git
 | 
				
			||||||
| 
						 | 
					@ -49,12 +61,3 @@
 | 
				
			||||||
[submodule "UnleashedRecomp/api"]
 | 
					[submodule "UnleashedRecomp/api"]
 | 
				
			||||||
	path = UnleashedRecomp/api
 | 
						path = UnleashedRecomp/api
 | 
				
			||||||
	url = https://github.com/hedge-dev/SWA.git
 | 
						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,6 +4,7 @@ if(NOT DEFINED ENV{VCPKG_ROOT})
 | 
				
			||||||
    message(FATAL_ERROR "VCPKG_ROOT is not defined!")
 | 
					    message(FATAL_ERROR "VCPKG_ROOT is not defined!")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
 | 
				
			||||||
set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty)
 | 
					set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty)
 | 
				
			||||||
set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools)
 | 
					set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools)
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 20)
 | 
					set(CMAKE_CXX_STANDARD 20)
 | 
				
			||||||
| 
						 | 
					@ -17,36 +18,16 @@ endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
 | 
					set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project("UnleashedRecomp-ALL")
 | 
					# Target Sandy Bridge for all projects
 | 
				
			||||||
 | 
					add_compile_options(
 | 
				
			||||||
if (APPLE)
 | 
					    -march=sandybridge
 | 
				
			||||||
    enable_language(OBJC OBJCXX)
 | 
					)
 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
 | 
					 | 
				
			||||||
    set(SDL_VULKAN_ENABLED ON CACHE BOOL "")
 | 
					 | 
				
			||||||
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_THIRDPARTY_ROOT})
 | 
				
			||||||
add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT})
 | 
					add_subdirectory(${UNLEASHED_RECOMP_TOOLS_ROOT})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					project("UnleashedRecomp-ALL")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Include sub-projects.
 | 
					# Include sub-projects.
 | 
				
			||||||
add_subdirectory("UnleashedRecompLib")
 | 
					add_subdirectory("UnleashedRecompLib")
 | 
				
			||||||
add_subdirectory("UnleashedRecomp")
 | 
					add_subdirectory("UnleashedRecomp")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,58 +113,6 @@
 | 
				
			||||||
                "CMAKE_BUILD_TYPE": "Release",
 | 
					                "CMAKE_BUILD_TYPE": "Release",
 | 
				
			||||||
                "CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
 | 
					                "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,14 +97,6 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
 | 
				
			||||||
        "os/linux/user_linux.cpp"
 | 
					        "os/linux/user_linux.cpp"
 | 
				
			||||||
        "os/linux/version_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()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(UNLEASHED_RECOMP_CPU_CXX_SOURCES
 | 
					set(UNLEASHED_RECOMP_CPU_CXX_SOURCES
 | 
				
			||||||
| 
						 | 
					@ -116,8 +108,15 @@ set(UNLEASHED_RECOMP_GPU_CXX_SOURCES
 | 
				
			||||||
    "gpu/imgui/imgui_common.cpp"
 | 
					    "gpu/imgui/imgui_common.cpp"
 | 
				
			||||||
    "gpu/imgui/imgui_font_builder.cpp"
 | 
					    "gpu/imgui/imgui_font_builder.cpp"
 | 
				
			||||||
    "gpu/imgui/imgui_snapshot.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
 | 
					set(UNLEASHED_RECOMP_APU_CXX_SOURCES
 | 
				
			||||||
    "apu/audio.cpp"
 | 
					    "apu/audio.cpp"
 | 
				
			||||||
    "apu/embedded_player.cpp"
 | 
					    "apu/embedded_player.cpp"
 | 
				
			||||||
| 
						 | 
					@ -214,10 +213,18 @@ set(UNLEASHED_RECOMP_THIRDPARTY_INCLUDES
 | 
				
			||||||
    "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include"
 | 
					    "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include"
 | 
				
			||||||
    "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb"
 | 
					    "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb"
 | 
				
			||||||
    "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/unordered_dense/include"
 | 
					    "${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}/bc_diff"
 | 
				
			||||||
    "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source"
 | 
					    "${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_source_files_properties(${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(UNLEASHED_RECOMP_CXX_SOURCES
 | 
					set(UNLEASHED_RECOMP_CXX_SOURCES
 | 
				
			||||||
| 
						 | 
					@ -292,55 +299,6 @@ if (WIN32)
 | 
				
			||||||
    if (${CMAKE_BUILD_TYPE} MATCHES "Release")
 | 
					    if (${CMAKE_BUILD_TYPE} MATCHES "Release")
 | 
				
			||||||
        target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
 | 
					        target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
 | 
				
			||||||
    endif()
 | 
					    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()
 | 
					else()
 | 
				
			||||||
    add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES})
 | 
					    add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
| 
						 | 
					@ -362,22 +320,24 @@ if (UNLEASHED_RECOMP_D3D12)
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (SDL_VULKAN_ENABLED)
 | 
					if (CMAKE_SYSTEM_NAME MATCHES "Linux")
 | 
				
			||||||
    target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
 | 
					    target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_package(directx-dxc REQUIRED)
 | 
				
			||||||
find_package(CURL REQUIRED)
 | 
					find_package(CURL REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (UNLEASHED_RECOMP_D3D12)
 | 
					if (UNLEASHED_RECOMP_D3D12)
 | 
				
			||||||
    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12)
 | 
					    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12)
 | 
				
			||||||
    add_custom_command(TARGET UnleashedRecomp POST_BUILD
 | 
					    add_custom_command(TARGET UnleashedRecomp POST_BUILD
 | 
				
			||||||
        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-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/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::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> ${CMAKE_CURRENT_BINARY_DIR}/D3D12
 | 
				
			||||||
        COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectXShaderCompiler,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp>
 | 
					       COMMAND_EXPAND_LISTS
 | 
				
			||||||
        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
 | 
					    target_link_libraries(UnleashedRecomp PRIVATE
 | 
				
			||||||
        Microsoft::DirectX-Headers 
 | 
					        Microsoft::DirectX-Headers 
 | 
				
			||||||
        Microsoft::DirectX-Guids 
 | 
					        Microsoft::DirectX-Guids 
 | 
				
			||||||
| 
						 | 
					@ -388,6 +348,8 @@ if (UNLEASHED_RECOMP_D3D12)
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (WIN32)
 | 
					if (WIN32)
 | 
				
			||||||
    target_link_libraries(UnleashedRecomp PRIVATE
 | 
					    target_link_libraries(UnleashedRecomp PRIVATE
 | 
				
			||||||
        comctl32
 | 
					        comctl32
 | 
				
			||||||
| 
						 | 
					@ -413,7 +375,6 @@ target_link_libraries(UnleashedRecomp PRIVATE
 | 
				
			||||||
    UnleashedRecompLib
 | 
					    UnleashedRecompLib
 | 
				
			||||||
    xxHash::xxhash
 | 
					    xxHash::xxhash
 | 
				
			||||||
    CURL::libcurl
 | 
					    CURL::libcurl
 | 
				
			||||||
    plume
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_include_directories(UnleashedRecomp PRIVATE
 | 
					target_include_directories(UnleashedRecomp PRIVATE
 | 
				
			||||||
| 
						 | 
					@ -450,11 +411,11 @@ function(compile_shader FILE_PATH TARGET_NAME)
 | 
				
			||||||
endfunction()
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function(compile_vertex_shader FILE_PATH)
 | 
					function(compile_vertex_shader FILE_PATH)
 | 
				
			||||||
    compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y -DUNLEASHED_RECOMP)
 | 
					    compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y)
 | 
				
			||||||
endfunction()
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function(compile_pixel_shader FILE_PATH)
 | 
					function(compile_pixel_shader FILE_PATH)
 | 
				
			||||||
    compile_shader(${FILE_PATH} ps_6_0 -DUNLEASHED_RECOMP)
 | 
					    compile_shader(${FILE_PATH} ps_6_0)
 | 
				
			||||||
endfunction()
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
compile_pixel_shader(blend_color_alpha_ps)
 | 
					compile_pixel_shader(blend_color_alpha_ps)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,101 +40,29 @@ GuestThreadContext::~GuestThreadContext()
 | 
				
			||||||
    g_userHeap.Free(thread);
 | 
					    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)
 | 
					static void GuestThreadFunc(GuestThreadHandle* hThread)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    hThread->suspended.wait(true);
 | 
					    hThread->suspended.wait(true);
 | 
				
			||||||
    GuestThread::Start(hThread->params);
 | 
					    GuestThread::Start(hThread->params);
 | 
				
			||||||
#ifdef USE_PTHREAD
 | 
					 | 
				
			||||||
    return nullptr;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params)
 | 
					GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params)
 | 
				
			||||||
    : params(params), suspended((params.flags & 0x1) != 0)
 | 
					    : params(params), suspended((params.flags & 0x1) != 0), thread(GuestThreadFunc, this)
 | 
				
			||||||
#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()
 | 
					GuestThreadHandle::~GuestThreadHandle()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef USE_PTHREAD
 | 
					 | 
				
			||||||
    pthread_join(thread, nullptr);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    if (thread.joinable())
 | 
					    if (thread.joinable())
 | 
				
			||||||
        thread.join();
 | 
					        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)
 | 
					uint32_t GuestThreadHandle::Wait(uint32_t timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(timeout == INFINITE);
 | 
					    assert(timeout == INFINITE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_PTHREAD
 | 
					 | 
				
			||||||
    pthread_join(thread, nullptr);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    if (thread.joinable())
 | 
					    if (thread.joinable())
 | 
				
			||||||
        thread.join();
 | 
					        thread.join();
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return STATUS_WAIT_0;
 | 
					    return STATUS_WAIT_0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -152,25 +80,27 @@ uint32_t GuestThread::Start(const GuestThreadParams& params)
 | 
				
			||||||
    return ctx.ppcContext.r3.u32;
 | 
					    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)
 | 
					GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    auto hThread = CreateKernelObject<GuestThreadHandle>(params);
 | 
					    auto hThread = CreateKernelObject<GuestThreadHandle>(params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (threadId != nullptr)
 | 
					    if (threadId != nullptr)
 | 
				
			||||||
    {
 | 
					        *threadId = GetThreadId(hThread->thread.get_id());
 | 
				
			||||||
        *threadId = hThread->GetThreadId();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return hThread;
 | 
					    return hThread;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t GuestThread::GetCurrentThreadId()
 | 
					uint32_t GuestThread::GetCurrentThreadId()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef USE_PTHREAD
 | 
					    return GetThreadId(std::this_thread::get_id());
 | 
				
			||||||
    return CalcThreadId(pthread_self());
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    return CalcThreadId(std::this_thread::get_id());
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void GuestThread::SetLastError(uint32_t error)
 | 
					void GuestThread::SetLastError(uint32_t error)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,15 +2,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <kernel/xdm.h>
 | 
					#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)
 | 
					#define CURRENT_THREAD_HANDLE uint32_t(-2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct GuestThreadContext
 | 
					struct GuestThreadContext
 | 
				
			||||||
| 
						 | 
					@ -33,17 +24,11 @@ struct GuestThreadHandle : KernelObject
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    GuestThreadParams params;
 | 
					    GuestThreadParams params;
 | 
				
			||||||
    std::atomic<bool> suspended;
 | 
					    std::atomic<bool> suspended;
 | 
				
			||||||
#ifdef USE_PTHREAD
 | 
					 | 
				
			||||||
    pthread_t thread;
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    std::thread thread;
 | 
					    std::thread thread;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GuestThreadHandle(const GuestThreadParams& params);
 | 
					    GuestThreadHandle(const GuestThreadParams& params);
 | 
				
			||||||
    ~GuestThreadHandle() override;
 | 
					    ~GuestThreadHandle() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t GetThreadId() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint32_t Wait(uint32_t timeout) override;
 | 
					    uint32_t Wait(uint32_t timeout) override;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										21
									
								
								UnleashedRecomp/gpu/rhi/LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								UnleashedRecomp/gpu/rhi/LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
							
								
								
									
										3923
									
								
								UnleashedRecomp/gpu/rhi/plume_d3d12.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3923
									
								
								UnleashedRecomp/gpu/rhi/plume_d3d12.cpp
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										481
									
								
								UnleashedRecomp/gpu/rhi/plume_d3d12.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										481
									
								
								UnleashedRecomp/gpu/rhi/plume_d3d12.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,481 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										262
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,262 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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"
 | 
				
			||||||
							
								
								
									
										281
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface_builders.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface_builders.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,281 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1819
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface_types.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1819
									
								
								UnleashedRecomp/gpu/rhi/plume_render_interface_types.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										4407
									
								
								UnleashedRecomp/gpu/rhi/plume_vulkan.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4407
									
								
								UnleashedRecomp/gpu/rhi/plume_vulkan.cpp
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										456
									
								
								UnleashedRecomp/gpu/rhi/plume_vulkan.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										456
									
								
								UnleashedRecomp/gpu/rhi/plume_vulkan.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,456 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 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,7 +37,6 @@
 | 
				
			||||||
#include <magic_enum/magic_enum.hpp>
 | 
					#include <magic_enum/magic_enum.hpp>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UNLEASHED_RECOMP
 | 
					 | 
				
			||||||
#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
 | 
					#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef UNLEASHED_RECOMP_D3D12
 | 
					#ifdef UNLEASHED_RECOMP_D3D12
 | 
				
			||||||
| 
						 | 
					@ -1838,7 +1837,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
 | 
				
			||||||
    g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
 | 
					    g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (auto& commandList : g_commandLists)
 | 
					    for (auto& commandList : g_commandLists)
 | 
				
			||||||
        commandList = g_queue->createCommandList();
 | 
					        commandList = g_device->createCommandList(RenderCommandListType::DIRECT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (auto& commandFence : g_commandFences)
 | 
					    for (auto& commandFence : g_commandFences)
 | 
				
			||||||
        commandFence = g_device->createCommandFence();
 | 
					        commandFence = g_device->createCommandFence();
 | 
				
			||||||
| 
						 | 
					@ -1847,7 +1846,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
 | 
				
			||||||
        queryPool = g_device->createQueryPool(NUM_QUERIES);
 | 
					        queryPool = g_device->createQueryPool(NUM_QUERIES);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
 | 
					    g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
 | 
				
			||||||
    g_copyCommandList = g_copyQueue->createCommandList();
 | 
					    g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY);
 | 
				
			||||||
    g_copyCommandFence = g_device->createCommandFence();
 | 
					    g_copyCommandFence = g_device->createCommandFence();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint32_t bufferCount = 2;
 | 
					    uint32_t bufferCount = 2;
 | 
				
			||||||
| 
						 | 
					@ -2075,21 +2074,23 @@ void Video::WaitForGPU()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    g_waitForGPUCount++;
 | 
					    g_waitForGPUCount++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Wait for all queued frames to finish.
 | 
					    if (g_vulkan)
 | 
				
			||||||
    for (size_t i = 0; i < NUM_FRAMES; i++)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (g_commandListStates[i])
 | 
					        g_device->waitIdle();
 | 
				
			||||||
        {
 | 
					    }
 | 
				
			||||||
            g_queue->waitForCommandFence(g_commandFences[i].get());
 | 
					    else 
 | 
				
			||||||
            g_commandListStates[i] = false;
 | 
					    {
 | 
				
			||||||
        }
 | 
					        for (size_t i = 0; i < NUM_FRAMES; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (g_commandListStates[i])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                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)
 | 
					static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
 | 
				
			||||||
| 
						 | 
					@ -5735,7 +5736,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
 | 
				
			||||||
                auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
 | 
					                auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        g_copyCommandList->copyTextureRegion(
 | 
					                        g_copyCommandList->copyTextureRegion(
 | 
				
			||||||
                            RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % ddsDesc.numMips, subresourceIndex / ddsDesc.numMips),
 | 
					                            RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
 | 
				
			||||||
                            RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
 | 
					                            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
 | 
				
			||||||
//#define PSO_CACHING_CLEANUP
 | 
					//#define PSO_CACHING_CLEANUP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <plume_render_interface.h>
 | 
					#include "rhi/plume_render_interface.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define D3DCLEAR_TARGET  0x1
 | 
					#define D3DCLEAR_TARGET  0x1
 | 
				
			||||||
#define D3DCLEAR_ZBUFFER 0x10
 | 
					#define D3DCLEAR_ZBUFFER 0x10
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -166,9 +166,6 @@ void UpdateChecker::visitWebsite()
 | 
				
			||||||
#elif defined(__linux__)
 | 
					#elif defined(__linux__)
 | 
				
			||||||
    std::string command = "xdg-open " + std::string(VISIT_URL) + " &";
 | 
					    std::string command = "xdg-open " + std::string(VISIT_URL) + " &";
 | 
				
			||||||
    std::system(command.c_str());
 | 
					    std::system(command.c_str());
 | 
				
			||||||
#elif defined(__APPLE__)
 | 
					 | 
				
			||||||
    std::string command = "open " + std::string(VISIT_URL) + " &";
 | 
					 | 
				
			||||||
    std::system(command.c_str());
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    static_assert(false, "Visit website not implemented for this platform.");
 | 
					    static_assert(false, "Visit website not implemented for this platform.");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -660,7 +660,7 @@ void KeQueryBasePriorityThread()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
 | 
					uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId());
 | 
					    assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->thread.get_id() == std::this_thread::get_id());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    hThread->suspended = true;
 | 
					    hThread->suspended = true;
 | 
				
			||||||
    hThread->suspended.wait(true);
 | 
					    hThread->suspended.wait(true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!exists)
 | 
					        if (!exists)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::filesystem::path rootPath;
 | 
					            std::string root = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
 | 
					            if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                rootPath = GetSavePath(true);
 | 
					                std::u8string savePathU8 = GetSavePath(true).u8string();
 | 
				
			||||||
 | 
					                root = (const char *)(savePathU8.c_str());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
 | 
					            else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                rootPath = GetGamePath() / "dlc";
 | 
					                root = GAME_INSTALL_DIRECTORY "/dlc";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                rootPath = GetGamePath();
 | 
					                root = GAME_INSTALL_DIRECTORY;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            const std::string root = (const char*)rootPath.u8string().c_str();
 | 
					 | 
				
			||||||
            XamRegisterContent(*pContentData, root);
 | 
					            XamRegisterContent(*pContentData, root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::error_code ec;
 | 
					            std::error_code ec;
 | 
				
			||||||
            std::filesystem::create_directory(rootPath, ec);
 | 
					            std::filesystem::create_directory(std::u8string_view((const char8_t*)(root.c_str())), ec);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            XamRootCreate(szRootName, root);
 | 
					            XamRootCreate(szRootName, root);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,5 @@
 | 
				
			||||||
#include <stdafx.h>
 | 
					#include <stdafx.h>
 | 
				
			||||||
#ifdef __x86_64__
 | 
					 | 
				
			||||||
#include <cpuid.h>
 | 
					#include <cpuid.h>
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#include <cpu/guest_thread.h>
 | 
					#include <cpu/guest_thread.h>
 | 
				
			||||||
#include <gpu/video.h>
 | 
					#include <gpu/video.h>
 | 
				
			||||||
#include <kernel/function.h>
 | 
					#include <kernel/function.h>
 | 
				
			||||||
| 
						 | 
					@ -71,10 +69,8 @@ void KiSystemStartup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
 | 
					    const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
 | 
				
			||||||
    const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
 | 
					    const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
 | 
				
			||||||
    const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str();
 | 
					    XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
 | 
				
			||||||
    const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str();
 | 
					    XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update");
 | 
				
			||||||
    XamRegisterContent(gameContent, gamePath);
 | 
					 | 
				
			||||||
    XamRegisterContent(updateContent, updatePath);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const auto saveFilePath = GetSaveFilePath(true);
 | 
					    const auto saveFilePath = GetSaveFilePath(true);
 | 
				
			||||||
    bool saveFileExists = std::filesystem::exists(saveFilePath);
 | 
					    bool saveFileExists = std::filesystem::exists(saveFilePath);
 | 
				
			||||||
| 
						 | 
					@ -106,7 +102,7 @@ void KiSystemStartup()
 | 
				
			||||||
    XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
 | 
					    XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::error_code ec;
 | 
					    std::error_code ec;
 | 
				
			||||||
    for (auto& file : std::filesystem::directory_iterator(GetGamePath() / "dlc", ec))
 | 
					    for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (file.is_directory())
 | 
					        if (file.is_directory())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					@ -169,10 +165,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path)
 | 
				
			||||||
    return entry;
 | 
					    return entry;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __x86_64__
 | 
					 | 
				
			||||||
__attribute__((constructor(101), target("no-avx,no-avx2"), noinline))
 | 
					__attribute__((constructor(101), target("no-avx,no-avx2"), noinline))
 | 
				
			||||||
void init()
 | 
					void init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef __x86_64__
 | 
				
			||||||
    uint32_t eax, ebx, ecx, edx;
 | 
					    uint32_t eax, ebx, ecx, edx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Execute CPUID for processor info and feature bits.
 | 
					    // Execute CPUID for processor info and feature bits.
 | 
				
			||||||
| 
						 | 
					@ -189,8 +185,8 @@ void init()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::_Exit(1);
 | 
					        std::_Exit(1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[])
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -236,7 +232,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Set the current working directory to the executable's path.
 | 
					        // Set the current working directory to the executable's path.
 | 
				
			||||||
        std::error_code ec;
 | 
					        std::error_code ec;
 | 
				
			||||||
        std::filesystem::current_path(os::process::GetExecutableRoot(), ec);
 | 
					        std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Config::Load();
 | 
					    Config::Load();
 | 
				
			||||||
| 
						 | 
					@ -325,7 +321,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
    HostStartup();
 | 
					    HostStartup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::filesystem::path modulePath;
 | 
					    std::filesystem::path modulePath;
 | 
				
			||||||
    bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath);
 | 
					    bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath);
 | 
				
			||||||
    bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
 | 
					    bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
 | 
				
			||||||
    if (runInstallerWizard)
 | 
					    if (runInstallerWizard)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -335,7 +331,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
            std::_Exit(1);
 | 
					            std::_Exit(1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller))
 | 
					        if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::_Exit(0);
 | 
					            std::_Exit(0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,7 @@ void ModLoader::Init()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        configIni = {};
 | 
					        configIni = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!configIni.read(GetGamePath() / "cpkredir.ini"))
 | 
					        if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini"))
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,11 +15,6 @@ std::filesystem::path os::process::GetExecutablePath()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::filesystem::path os::process::GetExecutableRoot()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return GetExecutablePath().remove_filename();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::filesystem::path os::process::GetWorkingDirectory()
 | 
					std::filesystem::path os::process::GetWorkingDirectory()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char cwd[PATH_MAX] = {};
 | 
					    char cwd[PATH_MAX] = {};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +0,0 @@
 | 
				
			||||||
#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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
#include <os/media.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool os::media::IsExternalMediaPlaying()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // This functionality is not supported in macOS.
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,97 +0,0 @@
 | 
				
			||||||
#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.
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,21 +0,0 @@
 | 
				
			||||||
#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;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +0,0 @@
 | 
				
			||||||
#include <os/user.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool os::user::IsDarkTheme()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
#include <os/version.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
os::version::OSVersion os::version::GetOSVersion()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(false && "Unimplemented.");
 | 
					 | 
				
			||||||
    return os::version::OSVersion();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,6 @@ namespace os::process
 | 
				
			||||||
    inline bool g_consoleVisible;
 | 
					    inline bool g_consoleVisible;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::filesystem::path GetExecutablePath();
 | 
					    std::filesystem::path GetExecutablePath();
 | 
				
			||||||
    std::filesystem::path GetExecutableRoot();
 | 
					 | 
				
			||||||
    std::filesystem::path GetWorkingDirectory();
 | 
					    std::filesystem::path GetWorkingDirectory();
 | 
				
			||||||
    bool SetWorkingDirectory(const std::filesystem::path& path);
 | 
					    bool SetWorkingDirectory(const std::filesystem::path& path);
 | 
				
			||||||
    bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
 | 
					    bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,6 +15,4 @@ namespace os::registry
 | 
				
			||||||
#include <os/win32/registry_win32.inl>
 | 
					#include <os/win32/registry_win32.inl>
 | 
				
			||||||
#elif defined(__linux__)
 | 
					#elif defined(__linux__)
 | 
				
			||||||
#include <os/linux/registry_linux.inl>
 | 
					#include <os/linux/registry_linux.inl>
 | 
				
			||||||
#elif defined(__APPLE__)
 | 
					 | 
				
			||||||
#include <os/macos/registry_macos.inl>
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,11 +10,6 @@ std::filesystem::path os::process::GetExecutablePath()
 | 
				
			||||||
    return std::filesystem::path(exePath);
 | 
					    return std::filesystem::path(exePath);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::filesystem::path os::process::GetExecutableRoot()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return GetExecutablePath().remove_filename();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
std::filesystem::path os::process::GetWorkingDirectory()
 | 
					std::filesystem::path os::process::GetWorkingDirectory()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    WCHAR workPath[MAX_PATH];
 | 
					    WCHAR workPath[MAX_PATH];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,42 +0,0 @@
 | 
				
			||||||
<?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>
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -20,7 +20,7 @@ std::unique_ptr<GuestTexture> g_upKBMIcons;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float g_sideMargins = DEFAULT_SIDE_MARGINS;
 | 
					float g_sideMargins = DEFAULT_SIDE_MARGINS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static std::vector<Button> g_buttons;
 | 
					std::vector<Button> g_buttons;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unordered_map<EButtonIcon, float> g_iconWidths =
 | 
					std::unordered_map<EButtonIcon, float> g_iconWidths =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -217,9 +217,6 @@ void GameWindow::Init(const char* sdlVideoDriver)
 | 
				
			||||||
    s_renderWindow = s_pWindow;
 | 
					    s_renderWindow = s_pWindow;
 | 
				
			||||||
#elif defined(__linux__)
 | 
					#elif defined(__linux__)
 | 
				
			||||||
    s_renderWindow = { info.info.x11.display, info.info.x11.window };
 | 
					    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
 | 
					#else
 | 
				
			||||||
    static_assert(false, "Unknown platform.");
 | 
					    static_assert(false, "Unknown platform.");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <plume_render_interface_types.h>
 | 
					#include <gpu/rhi/plume_render_interface_types.h>
 | 
				
			||||||
#include <user/config.h>
 | 
					#include <user/config.h>
 | 
				
			||||||
#include <sdl_events.h>
 | 
					#include <sdl_events.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1146,11 +1146,7 @@ static void PickerStart(bool folderMode) {
 | 
				
			||||||
    g_currentPickerVisible = true;
 | 
					    g_currentPickerVisible = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
 | 
					    // 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;
 | 
					    constexpr bool singleThreadMode = false;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    if (singleThreadMode)
 | 
					    if (singleThreadMode)
 | 
				
			||||||
        PickerThreadProcess();
 | 
					        PickerThreadProcess();
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ static ImFont* g_fntSeurat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::string g_text;
 | 
					std::string g_text;
 | 
				
			||||||
int g_result;
 | 
					int g_result;
 | 
				
			||||||
static std::vector<std::string> g_buttons;
 | 
					std::vector<std::string> g_buttons;
 | 
				
			||||||
int g_defaultButtonIndex;
 | 
					int g_defaultButtonIndex;
 | 
				
			||||||
int g_cancelButtonIndex;
 | 
					int g_cancelButtonIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
#include "paths.h"
 | 
					#include "paths.h"
 | 
				
			||||||
#include <os/process.h>
 | 
					#include <os/process.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::filesystem::path g_executableRoot = os::process::GetExecutableRoot();
 | 
					std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename();
 | 
				
			||||||
std::filesystem::path g_userPath = BuildUserPath();
 | 
					std::filesystem::path g_userPath = BuildUserPath();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool CheckPortable()
 | 
					bool CheckPortable()
 | 
				
			||||||
| 
						 | 
					@ -22,24 +22,18 @@ std::filesystem::path BuildUserPath()
 | 
				
			||||||
        userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY;
 | 
					        userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CoTaskMemFree(knownPath);
 | 
					    CoTaskMemFree(knownPath);
 | 
				
			||||||
#elif defined(__linux__) || defined(__APPLE__)
 | 
					#elif defined(__linux__)
 | 
				
			||||||
    const char* homeDir = getenv("HOME");
 | 
					    const char* homeDir = getenv("HOME");
 | 
				
			||||||
#if defined(__linux__)
 | 
					 | 
				
			||||||
    if (homeDir == nullptr)
 | 
					    if (homeDir == nullptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        homeDir = getpwuid(getuid())->pw_dir;
 | 
					        homeDir = getpwuid(getuid())->pw_dir;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (homeDir != nullptr)
 | 
					    if (homeDir != nullptr)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 | 
					        // Prefer to store in the .config directory if it exists. Use the home directory otherwise.
 | 
				
			||||||
        std::filesystem::path homePath = homeDir;
 | 
					        std::filesystem::path homePath = homeDir;
 | 
				
			||||||
#if defined(__linux__)
 | 
					 | 
				
			||||||
        std::filesystem::path configPath = homePath / ".config";
 | 
					        std::filesystem::path configPath = homePath / ".config";
 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
        std::filesystem::path configPath = homePath / "Library" / "Application Support";
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
        if (std::filesystem::exists(configPath))
 | 
					        if (std::filesystem::exists(configPath))
 | 
				
			||||||
            userPath = configPath / USER_DIRECTORY;
 | 
					            userPath = configPath / USER_DIRECTORY;
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,22 +10,15 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern std::filesystem::path g_executableRoot;
 | 
					extern std::filesystem::path g_executableRoot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline std::filesystem::path GetGamePath()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return GAME_INSTALL_DIRECTORY;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool CheckPortable();
 | 
					bool CheckPortable();
 | 
				
			||||||
std::filesystem::path BuildUserPath();
 | 
					std::filesystem::path BuildUserPath();
 | 
				
			||||||
const std::filesystem::path& GetUserPath();
 | 
					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)
 | 
					inline std::filesystem::path GetSavePath(bool checkForMods)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (checkForMods && !ModLoader::s_saveFilePath.empty())
 | 
					    if (checkForMods && !ModLoader::s_saveFilePath.empty())
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,6 @@ add_custom_command(
 | 
				
			||||||
        "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex"
 | 
					        "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex"
 | 
				
			||||||
        "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp"
 | 
					        "${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp"
 | 
				
			||||||
        "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml"
 | 
					        "${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml"
 | 
				
			||||||
    USES_TERMINAL
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_custom_command(
 | 
					add_custom_command(
 | 
				
			||||||
| 
						 | 
					@ -54,7 +53,6 @@ target_compile_definitions(XenosRecomp PRIVATE
 | 
				
			||||||
    XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\" 
 | 
					    XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\" 
 | 
				
			||||||
    XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\"
 | 
					    XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\"
 | 
				
			||||||
    XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\"
 | 
					    XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\"
 | 
				
			||||||
    UNLEASHED_RECOMP
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
file(GLOB XENOS_RECOMP_SOURCES 
 | 
					file(GLOB XENOS_RECOMP_SOURCES 
 | 
				
			||||||
| 
						 | 
					@ -72,7 +70,6 @@ add_custom_command(
 | 
				
			||||||
        "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar" 
 | 
					        "${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar" 
 | 
				
			||||||
        ${XENOS_RECOMP_SOURCES} 
 | 
					        ${XENOS_RECOMP_SOURCES} 
 | 
				
			||||||
        ${XENOS_RECOMP_INCLUDE}
 | 
					        ${XENOS_RECOMP_INCLUDE}
 | 
				
			||||||
    USES_TERMINAL
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_library(UnleashedRecompLib 
 | 
					add_library(UnleashedRecompLib 
 | 
				
			||||||
| 
						 | 
					@ -82,5 +79,4 @@ add_library(UnleashedRecompLib
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
 | 
					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")
 | 
					target_precompile_headers(UnleashedRecompLib PUBLIC "ppc/ppc_recomp_shared.h")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,21 +50,6 @@ You can also find the equivalent packages for your preferred distro.
 | 
				
			||||||
> [!NOTE]
 | 
					> [!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.
 | 
					> 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
 | 
					## 4. Build the Project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Windows
 | 
					### Windows
 | 
				
			||||||
| 
						 | 
					@ -96,22 +81,3 @@ cmake --build ./out/build/linux-release --target UnleashedRecomp
 | 
				
			||||||
```bash
 | 
					```bash
 | 
				
			||||||
./UnleashedRecomp
 | 
					./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
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								thirdparty/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -20,8 +20,3 @@ add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended"
 | 
				
			||||||
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap")
 | 
					add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap")
 | 
				
			||||||
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL")
 | 
					add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL")
 | 
				
			||||||
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer")
 | 
					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
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/D3D12MemoryAllocator
									
										
									
									
										vendored
									
									
										Submodule
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f
 | 
				
			||||||
							
								
								
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										86
									
								
								thirdparty/MoltenVK/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,86 +0,0 @@
 | 
				
			||||||
# 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
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/MoltenVK
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
Subproject commit 3a0b07a24a4a681ffe70b461b1f4333b2729e2ef
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/MoltenVK/SPIRV-Cross
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
Subproject commit 22b22f5685d868828be01c9ac00c31902e60afd9
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/Vulkan-Headers
									
										
									
									
										vendored
									
									
										Submodule
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7
 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/VulkanMemoryAllocator
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/VulkanMemoryAllocator
									
										
									
									
										vendored
									
									
										Submodule
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39
 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/plume
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								thirdparty/plume
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
Subproject commit fffeb35f836d8c945697ec82b735e77db401e2de
 | 
					 | 
				
			||||||
							
								
								
									
										1
									
								
								thirdparty/volk
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								thirdparty/volk
									
										
									
									
										vendored
									
									
										Submodule
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f
 | 
				
			||||||
| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
Subproject commit c5bfd90d87f2ed0db8cff5c19ea3aff0e161e527
 | 
					Subproject commit c017eb630ab917bffd3bc6a0a46995b49e7d8049
 | 
				
			||||||
| 
						 | 
					@ -1 +1 @@
 | 
				
			||||||
Subproject commit 990d03b28a27b50277ee5d8d942e1c5f873869d1
 | 
					Subproject commit 56738e5893ed7c4dc108996590475c52726623e3
 | 
				
			||||||
| 
						 | 
					@ -9,12 +9,8 @@
 | 
				
			||||||
            "name": "directx12-agility",
 | 
					            "name": "directx12-agility",
 | 
				
			||||||
            "platform": "windows"
 | 
					            "platform": "windows"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "directx-dxc",
 | 
				
			||||||
        "freetype",
 | 
					        "freetype",
 | 
				
			||||||
        "curl"
 | 
					        "curl"
 | 
				
			||||||
    ],
 | 
					    ]
 | 
				
			||||||
    "vcpkg-configuration": {
 | 
					 | 
				
			||||||
        "overlay-triplets": [
 | 
					 | 
				
			||||||
            "vcpkg/triplets"
 | 
					 | 
				
			||||||
        ]
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
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")
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,7 +0,0 @@
 | 
				
			||||||
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