Compare commits

...

4 commits

Author SHA1 Message Date
Hyper
901654fed1
Merge 7740f6587d into 9ace79a4d2 2025-08-03 22:52:30 -05:00
squidbus
9ace79a4d2
Switch to upstream plume. (#1645)
Some checks are pending
validate-internal / build (push) Waiting to run
2025-08-03 19:52:08 +03:00
squidbus
80e779afd9
Add support for macOS. (#745) 2025-08-03 18:56:42 +03:00
Hyper
7740f6587d Fix "Use Alternate Title" code not swapping logos for certain scenarios 2025-04-04 21:43:09 +01:00
59 changed files with 876 additions and 11828 deletions

View file

@ -210,3 +210,80 @@ jobs:
with:
name: UnleashedRecomp-Flatpak
path: ./${{ env.FLATPAK_ID }}.flatpak
build-macos:
name: Build macOS
runs-on: macos-15
strategy:
matrix:
arch: [ "arm64" ]
preset: ["macos-debug", "macos-release", "macos-relwithdebinfo"]
env:
CMAKE_PRESET: ${{ matrix.preset }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Checkout Private Repository
uses: actions/checkout@v4
with:
repository: ${{ secrets.ASSET_REPO }}
token: ${{ secrets.ASSET_REPO_TOKEN }}
path: ./private
- name: Setup latest Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }}
- name: Cache vcpkg
uses: actions/cache@v4
with:
path: |
./thirdparty/vcpkg/downloads
./thirdparty/vcpkg/packages
key: vcpkg-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
vcpkg-${{ runner.os }}-${{ matrix.arch }}-
- name: Install Dependencies (macOS)
run: |
brew install ninja
- name: Cache ccache Directory
uses: actions/cache@v4
with:
path: /tmp/ccache
key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }}
- name: Prepare Project
run: |
cp ./private/* ./UnleashedRecompLib/private
- name: Configure Project
env:
CCACHE_DIR: /tmp/ccache
run: cmake . --preset ${{ env.CMAKE_PRESET }} -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} -DSDL2MIXER_VORBIS=VORBISFILE -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
- name: Build Project
env:
CCACHE_DIR: /tmp/ccache
run: cmake --build ./out/build/${{ env.CMAKE_PRESET }} --target UnleashedRecomp
- name: Pack Release
run: |
codesign --deep -fs - "./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp/Unleashed Recompiled.app"
tar -czf UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz -C ./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp "Unleashed Recompiled.app"
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}
path: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz

21
.gitmodules vendored
View file

@ -16,21 +16,9 @@
[submodule "thirdparty/vcpkg"]
path = thirdparty/vcpkg
url = https://github.com/microsoft/vcpkg
[submodule "thirdparty/volk"]
path = thirdparty/volk
url = https://github.com/zeux/volk
[submodule "thirdparty/SDL"]
path = thirdparty/SDL
url = https://github.com/libsdl-org/SDL.git
[submodule "thirdparty/Vulkan-Headers"]
path = thirdparty/Vulkan-Headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "thirdparty/VulkanMemoryAllocator"]
path = thirdparty/VulkanMemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
[submodule "thirdparty/D3D12MemoryAllocator"]
path = thirdparty/D3D12MemoryAllocator
url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git
[submodule "thirdparty/stb"]
path = thirdparty/stb
url = https://github.com/nothings/stb.git
@ -61,3 +49,12 @@
[submodule "UnleashedRecomp/api"]
path = UnleashedRecomp/api
url = https://github.com/hedge-dev/SWA.git
[submodule "thirdparty/MoltenVK/MoltenVK"]
path = thirdparty/MoltenVK/MoltenVK
url = https://github.com/KhronosGroup/MoltenVK.git
[submodule "thirdparty/MoltenVK/SPIRV-Cross"]
path = thirdparty/MoltenVK/SPIRV-Cross
url = https://github.com/KhronosGroup/SPIRV-Cross.git
[submodule "thirdparty/plume"]
path = thirdparty/plume
url = https://github.com/renderbag/plume.git

View file

@ -4,7 +4,6 @@ if(NOT DEFINED ENV{VCPKG_ROOT})
message(FATAL_ERROR "VCPKG_ROOT is not defined!")
endif()
include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty)
set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools)
set(CMAKE_CXX_STANDARD 20)
@ -18,16 +17,36 @@ endif()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# Target Sandy Bridge for all projects
add_compile_options(
-march=sandybridge
)
project("UnleashedRecomp-ALL")
if (APPLE)
enable_language(OBJC OBJCXX)
endif()
if (CMAKE_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_TOOLS_ROOT})
project("UnleashedRecomp-ALL")
# Include sub-projects.
add_subdirectory("UnleashedRecompLib")
add_subdirectory("UnleashedRecomp")

View file

@ -113,6 +113,58 @@
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
}
},
{
"name": "macos-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": {
"value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"type": "FILEPATH"
},
"CMAKE_OSX_DEPLOYMENT_TARGET": "13.0"
},
"environment": {
"VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/2.0": {
"remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
},
{
"name": "macos-debug",
"displayName": "macOS-Debug",
"inherits": "macos-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "macos-relwithdebinfo",
"displayName": "macOS-RelWithDebInfo",
"inherits": "macos-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
},
{
"name": "macos-release",
"displayName": "macOS-Release",
"inherits": "macos-base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
}
}
]
}

View file

@ -97,6 +97,14 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
"os/linux/user_linux.cpp"
"os/linux/version_linux.cpp"
)
elseif (APPLE)
set(UNLEASHED_RECOMP_OS_CXX_SOURCES
"os/macos/logger_macos.cpp"
"os/macos/media_macos.cpp"
"os/macos/process_macos.cpp"
"os/macos/user_macos.cpp"
"os/macos/version_macos.cpp"
)
endif()
set(UNLEASHED_RECOMP_CPU_CXX_SOURCES
@ -108,18 +116,11 @@ set(UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/imgui/imgui_common.cpp"
"gpu/imgui/imgui_font_builder.cpp"
"gpu/imgui/imgui_snapshot.cpp"
"gpu/rhi/plume_vulkan.cpp"
)
if (UNLEASHED_RECOMP_D3D12)
list(APPEND UNLEASHED_RECOMP_GPU_CXX_SOURCES
"gpu/rhi/plume_d3d12.cpp"
)
endif()
set(UNLEASHED_RECOMP_APU_CXX_SOURCES
"apu/audio.cpp"
"apu/embedded_player.cpp"
"apu/embedded_player.cpp"
"apu/driver/sdl2_driver.cpp"
)
@ -149,16 +150,16 @@ set(UNLEASHED_RECOMP_PATCHES_CXX_SOURCES
set(UNLEASHED_RECOMP_UI_CXX_SOURCES
"ui/achievement_menu.cpp"
"ui/achievement_overlay.cpp"
"ui/achievement_overlay.cpp"
"ui/black_bar.cpp"
"ui/button_guide.cpp"
"ui/fader.cpp"
"ui/game_window.cpp"
"ui/game_window.cpp"
"ui/imgui_utils.cpp"
"ui/installer_wizard.cpp"
"ui/message_window.cpp"
"ui/options_menu.cpp"
"ui/options_menu_thumbnails.cpp"
"ui/options_menu_thumbnails.cpp"
"ui/tv_static.cpp"
)
@ -180,7 +181,7 @@ set(UNLEASHED_RECOMP_INSTALL_CXX_SOURCES
set(UNLEASHED_RECOMP_USER_CXX_SOURCES
"user/achievement_data.cpp"
"user/achievement_manager.cpp"
"user/config.cpp"
"user/config.cpp"
"user/registry.cpp"
"user/paths.cpp"
"user/persistent_data.cpp"
@ -213,25 +214,17 @@ set(UNLEASHED_RECOMP_THIRDPARTY_INCLUDES
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/magic_enum/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/stb"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/unordered_dense/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/volk"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/Vulkan-Headers/include"
"${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include"
"${UNLEASHED_RECOMP_TOOLS_ROOT}/bc_diff"
"${UNLEASHED_RECOMP_TOOLS_ROOT}/XenosRecomp/thirdparty/smol-v/source"
)
if (UNLEASHED_RECOMP_D3D12)
list(APPEND UNLEASHED_RECOMP_THIRDPARTY_INCLUDES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include")
list(APPEND UNLEASHED_RECOMP_THIRDPARTY_SOURCES "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp")
endif()
set_source_files_properties(${UNLEASHED_RECOMP_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
set(UNLEASHED_RECOMP_CXX_SOURCES
"app.cpp"
"exports.cpp"
"main.cpp"
"misc_impl.cpp"
"misc_impl.cpp"
"preload_executable.cpp"
"sdl_listener.cpp"
"stdafx.cpp"
@ -250,11 +243,11 @@ set(UNLEASHED_RECOMP_CXX_SOURCES
${UNLEASHED_RECOMP_USER_CXX_SOURCES}
${UNLEASHED_RECOMP_MOD_CXX_SOURCES}
${UNLEASHED_RECOMP_THIRDPARTY_SOURCES}
)
)
include("version.cmake")
set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt")
include("version.cmake")
set(VERSION_TXT "${PROJECT_SOURCE_DIR}/res/version.txt")
# Only show Git info and build type if not Release.
set(SHOW_GIT_INFO_AND_BUILD_TYPE 0)
@ -270,73 +263,120 @@ GenerateVersionSources(
BUILD_TYPE ${CMAKE_BUILD_TYPE}
SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE}
SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE}
)
)
if (WIN32)
# Create binary version number for Win32 integer attributes.
CreateVersionString(
VERSION_TXT ${VERSION_TXT}
OUTPUT_CSV 1
OUTPUT_VAR WIN32_VERSION_BINARY
)
# Create string version number for Win32 detailed attributes.
CreateVersionString(
VERSION_TXT ${VERSION_TXT}
BUILD_TYPE ${CMAKE_BUILD_TYPE}
SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE}
SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE}
OUTPUT_VAR WIN32_VERSION_STRING
)
# Create binary version number for Win32 integer attributes.
CreateVersionString(
VERSION_TXT ${VERSION_TXT}
OUTPUT_CSV 1
OUTPUT_VAR WIN32_VERSION_BINARY
)
# Create string version number for Win32 detailed attributes.
CreateVersionString(
VERSION_TXT ${VERSION_TXT}
BUILD_TYPE ${CMAKE_BUILD_TYPE}
SHOW_GIT_INFO ${SHOW_GIT_INFO_AND_BUILD_TYPE}
SHOW_BUILD_TYPE ${SHOW_GIT_INFO_AND_BUILD_TYPE}
OUTPUT_VAR WIN32_VERSION_STRING
)
# Set Win32 icon path.
set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico")
set(WIN32_ICON_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources/images/game_icon.ico")
configure_file("res/win32/res.rc.template" "${CMAKE_BINARY_DIR}/res.rc" @ONLY)
add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc")
# Hide console for release configurations.
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES} "${CMAKE_BINARY_DIR}/res.rc")
# Hide console for release configurations.
if (${CMAKE_BUILD_TYPE} MATCHES "Release")
target_link_options(UnleashedRecomp PRIVATE "/SUBSYSTEM:WINDOWS" "/ENTRY:mainCRTStartup")
endif()
elseif (APPLE)
# Create version number for app bundle.
CreateVersionString(
VERSION_TXT ${VERSION_TXT}
OUTPUT_VAR MACOS_BUNDLE_VERSION
)
add_executable(UnleashedRecomp MACOSX_BUNDLE
${UNLEASHED_RECOMP_CXX_SOURCES}
res/macos/game_icon.icns
)
set_source_files_properties(res/macos/game_icon.icns PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
set_target_properties(UnleashedRecomp PROPERTIES
OUTPUT_NAME "Unleashed Recompiled"
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/res/macos/MacOSXBundleInfo.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER hedge-dev.UnleashedRecomp
MACOSX_BUNDLE_BUNDLE_NAME "Unleashed Recompiled"
MACOSX_BUNDLE_BUNDLE_VERSION ${MACOS_BUNDLE_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${MACOS_BUNDLE_VERSION}
MACOSX_BUNDLE_ICON_FILE "game_icon.icns"
)
# Linking with MoltenVK directly would prevent using the system Vulkan loader to load with debug layers.
# Instead, copy the MoltenVK dylib to the app bundle along with an ICD file for the loader to find it.
# In the event the loader is not installed, the MoltenVK dylib can still be picked up directly in the app bundle.
set(MVK_BUNDLED_PATH "Resources/vulkan/icd.d")
set(MVK_DST "${CMAKE_CURRENT_BINARY_DIR}/Unleashed Recompiled.app/Contents/${MVK_BUNDLED_PATH}")
set_property(TARGET UnleashedRecomp APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLED_PATH}")
set(MVK_ICD_SRC "${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK/MoltenVK/MoltenVK/icd/MoltenVK_icd.json")
set(MVK_ICD_DST "${MVK_DST}/MoltenVK_icd.json")
set(MVK_DYLIB_SRC "${CMAKE_BINARY_DIR}/thirdparty/MoltenVK/libMoltenVK.dylib")
set(MVK_DYLIB_DST "${MVK_DST}/libMoltenVK.dylib")
add_custom_command(
OUTPUT ${MVK_DST}
COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DST})
add_custom_command(
OUTPUT ${MVK_ICD_DST}
DEPENDS ${MVK_ICD_SRC} ${MVK_DST}
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_ICD_SRC} ${MVK_ICD_DST})
add_custom_command(
OUTPUT ${MVK_DYLIB_DST}
DEPENDS ${MVK_DYLIB_SRC} ${MVK_DST}
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST})
add_dependencies(CopyMoltenVK MoltenVK)
add_dependencies(UnleashedRecomp CopyMoltenVK)
else()
add_executable(UnleashedRecomp ${UNLEASHED_RECOMP_CXX_SOURCES})
endif()
if (UNLEASHED_RECOMP_FLATPAK)
target_compile_definitions(UnleashedRecomp PRIVATE
"UNLEASHED_RECOMP_FLATPAK"
"GAME_INSTALL_DIRECTORY=\"/var/data\""
target_compile_definitions(UnleashedRecomp PRIVATE
"UNLEASHED_RECOMP_FLATPAK"
"GAME_INSTALL_DIRECTORY=\"/var/data\""
)
endif()
if (UNLEASHED_RECOMP_D3D12)
find_package(directx-headers CONFIG REQUIRED)
find_package(directx12-agility CONFIG REQUIRED)
target_compile_definitions(UnleashedRecomp PRIVATE
UNLEASHED_RECOMP_D3D12
D3D12MA_USING_DIRECTX_HEADERS
D3D12MA_OPTIONS16_SUPPORTED
target_compile_definitions(UnleashedRecomp PRIVATE
UNLEASHED_RECOMP_D3D12
D3D12MA_USING_DIRECTX_HEADERS
D3D12MA_OPTIONS16_SUPPORTED
)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
if (SDL_VULKAN_ENABLED)
target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
endif()
find_package(directx-dxc REQUIRED)
find_package(CURL REQUIRED)
if (UNLEASHED_RECOMP_D3D12)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12)
add_custom_command(TARGET UnleashedRecomp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> ${CMAKE_CURRENT_BINARY_DIR}/D3D12
COMMAND_EXPAND_LISTS
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectXShaderCompiler,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DXIL,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp>
COMMAND_EXPAND_LISTS
)
find_file(DIRECTX_DXIL_LIBRARY "dxil.dll")
file(COPY ${DIRECTX_DXIL_LIBRARY} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(UnleashedRecomp PRIVATE
Microsoft::DirectX-Headers
@ -348,19 +388,17 @@ if (UNLEASHED_RECOMP_D3D12)
)
endif()
file(CHMOD ${DIRECTX_DXC_TOOL} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
if (WIN32)
target_link_libraries(UnleashedRecomp PRIVATE
comctl32
comctl32
dwmapi
ntdll
ntdll
Shcore
Synchronization
winmm
windowsapp
)
endif()
endif()
target_link_libraries(UnleashedRecomp PRIVATE
fmt::fmt
@ -375,6 +413,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
UnleashedRecompLib
xxHash::xxhash
CURL::libcurl
plume
)
target_include_directories(UnleashedRecomp PRIVATE
@ -411,16 +450,16 @@ function(compile_shader FILE_PATH TARGET_NAME)
endfunction()
function(compile_vertex_shader FILE_PATH)
compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y)
compile_shader(${FILE_PATH} vs_6_0 -fvk-invert-y -DUNLEASHED_RECOMP)
endfunction()
function(compile_pixel_shader FILE_PATH)
compile_shader(${FILE_PATH} ps_6_0)
compile_shader(${FILE_PATH} ps_6_0 -DUNLEASHED_RECOMP)
endfunction()
compile_pixel_shader(blend_color_alpha_ps)
compile_vertex_shader(copy_vs)
compile_pixel_shader(copy_color_ps)
compile_pixel_shader(blend_color_alpha_ps)
compile_vertex_shader(copy_vs)
compile_pixel_shader(copy_color_ps)
compile_pixel_shader(copy_depth_ps)
compile_pixel_shader(csd_filter_ps)
compile_vertex_shader(csd_no_tex_vs)
@ -434,7 +473,7 @@ compile_pixel_shader(gamma_correction_ps)
compile_pixel_shader(imgui_ps)
compile_vertex_shader(imgui_vs)
compile_pixel_shader(movie_ps)
compile_vertex_shader(movie_vs)
compile_vertex_shader(movie_vs)
compile_pixel_shader(resolve_msaa_color_2x)
compile_pixel_shader(resolve_msaa_color_4x)
compile_pixel_shader(resolve_msaa_color_8x)
@ -444,7 +483,7 @@ compile_pixel_shader(resolve_msaa_depth_8x)
set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources")
set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res")
## Miscellaneous ##
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/bc_diff/button_bc_diff.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/bc_diff/button_bc_diff.bin" ARRAY_NAME "g_button_bc_diff" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/font/im_font_atlas.bin" DEST_FILE "${RESOURCES_OUTPUT_PATH}/font/im_font_atlas.bin" ARRAY_NAME "g_im_font_atlas" COMPRESSION_TYPE "zstd")
@ -456,7 +495,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/co
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/kbm.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/kbm.dds" ARRAY_NAME "g_kbm" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select.dds" ARRAY_NAME "g_select" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/light.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/light.dds" ARRAY_NAME "g_light" COMPRESSION_TYPE "zstd")
## Installer ##
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/arrow_circle.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/arrow_circle.dds" ARRAY_NAME "g_arrow_circle" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_001.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_001.dds" ARRAY_NAME "g_install_001" COMPRESSION_TYPE "zstd")
@ -468,23 +507,23 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/in
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_007.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_007.dds" ARRAY_NAME "g_install_007" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/install_008.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/install_008.dds" ARRAY_NAME "g_install_008" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/miles_electric_icon.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/miles_electric_icon.dds" ARRAY_NAME "g_miles_electric_icon" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/installer/pulse_install.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/installer/pulse_install.dds" ARRAY_NAME "g_pulse_install" COMPRESSION_TYPE "zstd")
## Options Menu ##
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/achievement_notifications.dds" ARRAY_NAME "g_achievement_notifications" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_ps.dds" ARRAY_NAME "g_allow_background_input_ps" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/allow_background_input_xb.dds" ARRAY_NAME "g_allow_background_input_xb" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_none.dds" ARRAY_NAME "g_antialiasing_none" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_2x.dds" ARRAY_NAME "g_antialiasing_2x" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_4x.dds" ARRAY_NAME "g_antialiasing_4x" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/antialiasing_8x.dds" ARRAY_NAME "g_antialiasing_8x" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/aspect_ratio.dds" ARRAY_NAME "g_aspect_ratio" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/battle_theme.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/battle_theme.dds" ARRAY_NAME "g_battle_theme" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/brightness.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/brightness.dds" ARRAY_NAME "g_brightness" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_stereo.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_stereo.dds" ARRAY_NAME "g_channel_stereo" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/channel_surround.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/channel_surround.dds" ARRAY_NAME "g_channel_surround" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_ps.dds" ARRAY_NAME "g_control_tutorial_ps" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/control_tutorial_xb.dds" ARRAY_NAME "g_control_tutorial_xb" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/controller_icons.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/controller_icons.dds" ARRAY_NAME "g_controller_icons" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/default.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/default.dds" ARRAY_NAME "g_default" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/effects_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/effects_volume.dds" ARRAY_NAME "g_effects_volume" COMPRESSION_TYPE "zstd")
@ -500,7 +539,7 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_off.dds" ARRAY_NAME "g_motion_blur_off" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_original.dds" ARRAY_NAME "g_motion_blur_original" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/motion_blur_enhanced.dds" ARRAY_NAME "g_motion_blur_enhanced" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fit.dds" ARRAY_NAME "g_movie_scale_fit" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/movie_scale_fill.dds" ARRAY_NAME "g_movie_scale_fill" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_attenuation.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_attenuation.dds" ARRAY_NAME "g_music_attenuation" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/music_volume.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/music_volume.dds" ARRAY_NAME "g_music_volume" COMPRESSION_TYPE "zstd")
@ -509,34 +548,34 @@ BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/op
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x2048.dds" ARRAY_NAME "g_shadow_resolution_x2048" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x4096.dds" ARRAY_NAME "g_shadow_resolution_x4096" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/shadow_resolution_x8192.dds" ARRAY_NAME "g_shadow_resolution_x8192" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_ps.dds" ARRAY_NAME "g_time_of_day_transition_playstation" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/time_transition_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/time_transition_xb.dds" ARRAY_NAME "g_time_of_day_transition_xbox" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_false.dds" ARRAY_NAME "g_transparency_antialiasing_false" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/transparency_antialiasing_true.dds" ARRAY_NAME "g_transparency_antialiasing_true" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_centre.dds" ARRAY_NAME "g_ui_alignment_centre" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/ui_alignment_edge.dds" ARRAY_NAME "g_ui_alignment_edge" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vertical_camera.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vertical_camera.dds" ARRAY_NAME "g_vertical_camera" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/voice_language.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/voice_language.dds" ARRAY_NAME "g_voice_language" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_ps.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_ps.dds" ARRAY_NAME "g_vibration_ps" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vibration_xb.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vibration_xb.dds" ARRAY_NAME "g_vibration_xb" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_on.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_on.dds" ARRAY_NAME "g_vsync_on" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/vsync_off.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/vsync_off.dds" ARRAY_NAME "g_vsync_off" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/window_size.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/window_size.dds" ARRAY_NAME "g_window_size" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/thumbnails/xbox_color_correction.dds" ARRAY_NAME "g_xbox_color_correction" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/miles_electric.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/miles_electric.dds" ARRAY_NAME "g_miles_electric" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static.dds" ARRAY_NAME "g_options_static" COMPRESSION_TYPE "zstd")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/options_menu/options_static_flash.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/options_menu/options_static_flash.dds" ARRAY_NAME "g_options_static_flash" COMPRESSION_TYPE "zstd")
## Game Icon ##
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_NAME "g_game_icon")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon_night.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon_night.bmp" ARRAY_NAME "g_game_icon_night")
## Audio ##
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/music/installer.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/music/installer.ogg" ARRAY_NAME "g_installer_music")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_cursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_cursor.ogg" ARRAY_NAME "g_sys_worldmap_cursor")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_worldmap_finaldecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_worldmap_finaldecide.ogg" ARRAY_NAME "g_sys_worldmap_finaldecide")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecansel.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecansel.ogg" ARRAY_NAME "g_sys_actstg_pausecansel")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausecursor.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausecursor.ogg" ARRAY_NAME "g_sys_actstg_pausecursor")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausedecide.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausedecide.ogg" ARRAY_NAME "g_sys_actstg_pausedecide")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinclose.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinclose.ogg" ARRAY_NAME "g_sys_actstg_pausewinclose")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen")
BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/sounds/sys_actstg_pausewinopen.ogg" DEST_FILE "${RESOURCES_OUTPUT_PATH}/sounds/sys_actstg_pausewinopen.ogg" ARRAY_NAME "g_sys_actstg_pausewinopen")

View file

@ -40,29 +40,101 @@ GuestThreadContext::~GuestThreadContext()
g_userHeap.Free(thread);
}
#ifdef USE_PTHREAD
static size_t GetStackSize()
{
// Cache as this should not change.
static size_t stackSize = 0;
if (stackSize == 0)
{
// 8 MiB is a typical default.
constexpr auto defaultSize = 8 * 1024 * 1024;
struct rlimit lim;
const auto ret = getrlimit(RLIMIT_STACK, &lim);
if (ret == 0 && lim.rlim_cur < defaultSize)
{
// Use what the system allows.
stackSize = lim.rlim_cur;
}
else
{
stackSize = defaultSize;
}
}
return stackSize;
}
static void* GuestThreadFunc(void* arg)
{
GuestThreadHandle* hThread = (GuestThreadHandle*)arg;
#else
static void GuestThreadFunc(GuestThreadHandle* hThread)
{
#endif
hThread->suspended.wait(true);
GuestThread::Start(hThread->params);
#ifdef USE_PTHREAD
return nullptr;
#endif
}
GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params)
: params(params), suspended((params.flags & 0x1) != 0), thread(GuestThreadFunc, this)
: params(params), suspended((params.flags & 0x1) != 0)
#ifdef USE_PTHREAD
{
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, GetStackSize());
const auto ret = pthread_create(&thread, &attr, GuestThreadFunc, this);
if (ret != 0) {
fprintf(stderr, "pthread_create failed with error code 0x%X.\n", ret);
return;
}
}
#else
, thread(GuestThreadFunc, this)
{
}
#endif
GuestThreadHandle::~GuestThreadHandle()
{
#ifdef USE_PTHREAD
pthread_join(thread, nullptr);
#else
if (thread.joinable())
thread.join();
#endif
}
template <typename ThreadType>
static uint32_t CalcThreadId(const ThreadType& id)
{
if constexpr (sizeof(id) == 4)
return *reinterpret_cast<const uint32_t*>(&id);
else
return XXH32(&id, sizeof(id), 0);
}
uint32_t GuestThreadHandle::GetThreadId() const
{
#ifdef USE_PTHREAD
return CalcThreadId(thread);
#else
return CalcThreadId(thread.get_id());
#endif
}
uint32_t GuestThreadHandle::Wait(uint32_t timeout)
{
assert(timeout == INFINITE);
#ifdef USE_PTHREAD
pthread_join(thread, nullptr);
#else
if (thread.joinable())
thread.join();
#endif
return STATUS_WAIT_0;
}
@ -80,27 +152,25 @@ uint32_t GuestThread::Start(const GuestThreadParams& params)
return ctx.ppcContext.r3.u32;
}
static uint32_t GetThreadId(const std::thread::id& id)
{
if constexpr (sizeof(id) == 4)
return *reinterpret_cast<const uint32_t*>(&id);
else
return XXH32(&id, sizeof(id), 0);
}
GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId)
{
auto hThread = CreateKernelObject<GuestThreadHandle>(params);
if (threadId != nullptr)
*threadId = GetThreadId(hThread->thread.get_id());
{
*threadId = hThread->GetThreadId();
}
return hThread;
}
uint32_t GuestThread::GetCurrentThreadId()
{
return GetThreadId(std::this_thread::get_id());
#ifdef USE_PTHREAD
return CalcThreadId(pthread_self());
#else
return CalcThreadId(std::this_thread::get_id());
#endif
}
void GuestThread::SetLastError(uint32_t error)

View file

@ -2,6 +2,15 @@
#include <kernel/xdm.h>
// Use pthreads directly on macOS to be able to increase default stack size.
#ifdef __APPLE__
#define USE_PTHREAD 1
#endif
#ifdef USE_PTHREAD
#include <pthread.h>
#endif
#define CURRENT_THREAD_HANDLE uint32_t(-2)
struct GuestThreadContext
@ -24,11 +33,17 @@ struct GuestThreadHandle : KernelObject
{
GuestThreadParams params;
std::atomic<bool> suspended;
#ifdef USE_PTHREAD
pthread_t thread;
#else
std::thread thread;
#endif
GuestThreadHandle(const GuestThreadParams& params);
~GuestThreadHandle() override;
uint32_t GetThreadId() const;
uint32_t Wait(uint32_t timeout) override;
};

View file

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 renderbag and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because it is too large Load diff

View file

@ -1,481 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include "plume_render_interface.h"
#include <map>
#include <mutex>
#include <unordered_map>
#include <directx/d3d12.h>
#include <dxgi1_4.h>
#include "D3D12MemAlloc.h"
namespace plume {
struct D3D12Buffer;
struct D3D12CommandQueue;
struct D3D12Device;
struct D3D12GraphicsPipeline;
struct D3D12Interface;
struct D3D12Pipeline;
struct D3D12Pool;
struct D3D12PipelineLayout;
struct D3D12Texture;
struct D3D12DescriptorHeapAllocator {
enum : uint32_t {
INVALID_OFFSET = 0xFFFFFFFFU
};
// Reference implementation http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
struct FreeBlock;
typedef std::map<uint32_t, FreeBlock> OffsetFreeBlockMap;
typedef std::multimap<uint32_t, OffsetFreeBlockMap::iterator> SizeFreeBlockMap;
struct FreeBlock {
uint32_t size;
SizeFreeBlockMap::iterator sizeMapIterator;
FreeBlock(uint32_t size) {
this->size = size;
}
};
ID3D12DescriptorHeap *heap = nullptr;
uint32_t heapSize = 0;
uint32_t freeSize = 0;
D3D12Device *device = nullptr;
D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle = {};
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle = {};
UINT descriptorHandleIncrement = 0;
OffsetFreeBlockMap offsetFreeBlockMap;
SizeFreeBlockMap sizeFreeBlockMap;
std::mutex allocationMutex;
D3D12DescriptorHeapAllocator(D3D12Device *device, uint32_t heapSize, D3D12_DESCRIPTOR_HEAP_TYPE heapType);
~D3D12DescriptorHeapAllocator();
void addFreeBlock(uint32_t offset, uint32_t size);
uint32_t allocate(uint32_t size);
void free(uint32_t offset, uint32_t size);
D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleAt(uint32_t index) const;
D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandleAt(uint32_t index) const;
};
struct D3D12DescriptorSet : RenderDescriptorSet {
D3D12Device *device = nullptr;
struct HeapAllocation {
uint32_t offset = 0;
uint32_t count = 0;
};
HeapAllocation viewAllocation;
HeapAllocation samplerAllocation;
std::vector<RenderDescriptorRangeType> descriptorTypes;
std::vector<uint32_t> descriptorHeapIndices;
uint32_t descriptorTypeMaxIndex = 0;
D3D12DescriptorSet(D3D12Device *device, const RenderDescriptorSetDesc &desc);
~D3D12DescriptorSet() override;
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
void setSRV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *viewDesc);
void setUAV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *viewDesc);
void setCBV(uint32_t descriptorIndex, ID3D12Resource *resource, uint64_t bufferSize);
};
struct D3D12SwapChain : RenderSwapChain {
IDXGISwapChain3 *d3d = nullptr;
HANDLE waitableObject = 0;
D3D12CommandQueue *commandQueue = nullptr;
RenderWindow renderWindow = {};
std::vector<D3D12Texture> textures;
uint32_t textureCount = 0;
RenderFormat format = RenderFormat::UNKNOWN;
DXGI_FORMAT nativeFormat = DXGI_FORMAT_UNKNOWN;
uint32_t width = 0;
uint32_t height = 0;
uint32_t refreshRate = 0;
bool vsyncEnabled = true;
uint32_t maxFrameLatency = 0;
D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
~D3D12SwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
void wait() override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;
uint32_t getTextureCount() const override;
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
RenderWindow getWindow() const override;
bool isEmpty() const override;
uint32_t getRefreshRate() const override;
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
void setTextures();
};
struct D3D12Framebuffer : RenderFramebuffer {
D3D12Device *device = nullptr;
uint32_t width = 0;
uint32_t height = 0;
std::vector<const D3D12Texture *> colorTargets;
const D3D12Texture *depthTarget = nullptr;
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> colorHandles;
D3D12_CPU_DESCRIPTOR_HANDLE depthHandle = {};
D3D12Framebuffer(D3D12Device *device, const RenderFramebufferDesc &desc);
~D3D12Framebuffer() override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
};
struct D3D12QueryPool : RenderQueryPool {
D3D12Device *device = nullptr;
ID3D12QueryHeap *d3d = nullptr;
std::vector<uint64_t> results;
std::unique_ptr<RenderBuffer> readbackBuffer;
D3D12QueryPool(D3D12Device *device, uint32_t queryCount);
virtual ~D3D12QueryPool() override;
virtual void queryResults() override;
virtual const uint64_t *getResults() const override;
virtual uint32_t getCount() const override;
};
struct D3D12CommandList : RenderCommandList {
ID3D12GraphicsCommandList9 *d3d = nullptr;
ID3D12CommandAllocator *commandAllocator = nullptr;
D3D12Device *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
const D3D12Framebuffer *targetFramebuffer = nullptr;
bool targetFramebufferSamplePositionsSet = false;
bool open = false;
const D3D12PipelineLayout *activeComputePipelineLayout = nullptr;
const D3D12PipelineLayout *activeGraphicsPipelineLayout = nullptr;
const D3D12GraphicsPipeline *activeGraphicsPipeline = nullptr;
bool descriptorHeapsSet = false;
D3D12_PRIMITIVE_TOPOLOGY activeTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
bool activeSamplePositions = false;
D3D12CommandList(D3D12Device *device, RenderCommandListType type);
~D3D12CommandList() override;
void begin() override;
void end() override;
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
void setPipeline(const RenderPipeline *pipeline) override;
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setIndexBuffer(const RenderIndexBufferView *view) override;
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
void setViewports(const RenderViewport *viewports, uint32_t count) override;
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
void discardTexture(const RenderTexture* texture) override;
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
void checkDescriptorHeaps();
void notifyDescriptorHeapWasChangedExternally();
void checkTopology();
void checkFramebufferSamplePositions();
void setSamplePositions(const RenderTexture *texture);
void resetSamplePositions();
void setDescriptorSet(const D3D12PipelineLayout *activePipelineLayout, RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute);
void setRootDescriptorTable(D3D12DescriptorHeapAllocator *heapAllocator, D3D12DescriptorSet::HeapAllocation &heapAllocation, uint32_t rootIndex, bool setCompute);
void setRootDescriptor(const D3D12PipelineLayout *activePipelineLayout, RenderBufferReference bufferReference, uint32_t setIndex, bool setCompute);
};
struct D3D12CommandFence : RenderCommandFence {
ID3D12Fence *d3d = nullptr;
D3D12Device *device = nullptr;
HANDLE fenceEvent = 0;
UINT64 fenceValue = 0;
D3D12CommandFence(D3D12Device *device);
~D3D12CommandFence() override;
};
struct D3D12CommandSemaphore : RenderCommandSemaphore {
ID3D12Fence *d3d = nullptr;
D3D12Device *device = nullptr;
UINT64 semaphoreValue = 0;
D3D12CommandSemaphore(D3D12Device *device);
~D3D12CommandSemaphore() override;
};
struct D3D12CommandQueue : RenderCommandQueue {
ID3D12CommandQueue *d3d = nullptr;
D3D12Device *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
D3D12CommandQueue(D3D12Device *device, RenderCommandListType type);
~D3D12CommandQueue() override;
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t newFrameLatency) override;
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
void waitForCommandFence(RenderCommandFence *fence) override;
};
struct D3D12Buffer : RenderBuffer {
ID3D12Resource *d3d = nullptr;
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
D3D12Device *device = nullptr;
D3D12MA::Allocation *allocation = nullptr;
D3D12Pool *pool = nullptr;
RenderBufferDesc desc;
D3D12Buffer() = default;
D3D12Buffer(D3D12Device *device, D3D12Pool *pool, const RenderBufferDesc &desc);
~D3D12Buffer() override;
void *map(uint32_t subresource, const RenderRange *readRange) override;
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
void setName(const std::string &name) override;
uint64_t getDeviceAddress() const override;
};
struct D3D12BufferFormattedView : RenderBufferFormattedView {
RenderFormat format = RenderFormat::UNKNOWN;
D3D12Buffer *buffer = nullptr;
D3D12BufferFormattedView(D3D12Buffer *buffer, RenderFormat format);
~D3D12BufferFormattedView() override;
};
struct D3D12Texture : RenderTexture {
ID3D12Resource *d3d = nullptr;
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
RenderTextureLayout layout = RenderTextureLayout::UNKNOWN;
D3D12Device *device = nullptr;
D3D12MA::Allocation *allocation = nullptr;
D3D12Pool *pool = nullptr;
RenderTextureDesc desc;
uint32_t targetAllocatorOffset = 0;
uint32_t targetEntryCount = 0;
bool targetHeapDepth = false;
D3D12Texture() = default;
D3D12Texture(D3D12Device *device, D3D12Pool *pool, const RenderTextureDesc &desc);
~D3D12Texture() override;
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
void setName(const std::string &name) override;
void createRenderTargetHeap();
void createDepthStencilHeap();
void releaseTargetHeap();
};
struct D3D12TextureView : RenderTextureView {
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
D3D12Texture *texture = nullptr;
RenderTextureViewDimension dimension = RenderTextureViewDimension::UNKNOWN;
uint32_t mipLevels = 0;
uint32_t mipSlice = 0;
uint32_t shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
D3D12TextureView(D3D12Texture *texture, const RenderTextureViewDesc &desc);
~D3D12TextureView() override;
};
struct D3D12AccelerationStructure :RenderAccelerationStructure {
D3D12Device *device = nullptr;
const D3D12Buffer *buffer = nullptr;
uint64_t offset = 0;
uint64_t size = 0;
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
D3D12AccelerationStructure(D3D12Device *device, const RenderAccelerationStructureDesc &desc);
~D3D12AccelerationStructure() override;
};
struct D3D12Pool : RenderPool {
D3D12MA::Pool *d3d = nullptr;
D3D12Device *device = nullptr;
RenderPoolDesc desc;
D3D12Pool(D3D12Device *device, const RenderPoolDesc &desc, bool gpuUploadHeapFallback);
~D3D12Pool() override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
};
struct D3D12Shader : RenderShader {
const void* data = nullptr;
uint64_t size = 0;
std::string entryPointName;
D3D12Device *device = nullptr;
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
D3D12Shader(D3D12Device *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
~D3D12Shader() override;
};
struct D3D12Sampler : RenderSampler {
D3D12_SAMPLER_DESC samplerDesc = {};
D3D12Device *device = nullptr;
RenderBorderColor borderColor = RenderBorderColor::UNKNOWN;
RenderShaderVisibility shaderVisibility = RenderShaderVisibility::UNKNOWN;
D3D12Sampler(D3D12Device *device, const RenderSamplerDesc &desc);
~D3D12Sampler() override;
};
struct D3D12Pipeline : RenderPipeline {
enum class Type {
Unknown,
Compute,
Graphics,
Raytracing
};
D3D12Device *device = nullptr;
Type type = Type::Unknown;
D3D12Pipeline(D3D12Device *device, Type type);
virtual ~D3D12Pipeline() override;
};
struct D3D12ComputePipeline : D3D12Pipeline {
ID3D12PipelineState *d3d = nullptr;
D3D12ComputePipeline(D3D12Device *device, const RenderComputePipelineDesc &desc);
~D3D12ComputePipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12GraphicsPipeline : D3D12Pipeline {
ID3D12PipelineState *d3d = nullptr;
std::vector<RenderInputSlot> inputSlots;
D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
D3D12GraphicsPipeline(D3D12Device *device, const RenderGraphicsPipelineDesc &desc);
~D3D12GraphicsPipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12RaytracingPipeline : D3D12Pipeline {
ID3D12StateObject *stateObject = nullptr;
ID3D12StateObjectProperties *stateObjectProperties = nullptr;
std::vector<void *> programShaderIdentifiers;
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
const D3D12PipelineLayout *pipelineLayout = nullptr;
D3D12RaytracingPipeline(D3D12Device *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
~D3D12RaytracingPipeline() override;
virtual void setName(const std::string& name) const override;
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct D3D12PipelineLayout : RenderPipelineLayout {
ID3D12RootSignature *rootSignature = nullptr;
D3D12Device *device = nullptr;
std::vector<RenderPushConstantRange> pushConstantRanges;
std::vector<uint32_t> setViewRootIndices;
std::vector<uint32_t> setSamplerRootIndices;
std::vector<std::pair<uint32_t, RenderRootDescriptorType>> rootDescriptorRootIndicesAndTypes;
uint32_t setCount = 0;
uint32_t rootCount = 0;
D3D12PipelineLayout(D3D12Device *device, const RenderPipelineLayoutDesc &desc);
~D3D12PipelineLayout() override;
};
struct D3D12Device : RenderDevice {
ID3D12Device8 *d3d = nullptr;
D3D12Interface *renderInterface = nullptr;
IDXGIAdapter1 *adapter = nullptr;
D3D12MA::Allocator *allocator = nullptr;
D3D_SHADER_MODEL shaderModel = D3D_SHADER_MODEL(0);
std::unique_ptr<RenderPipelineLayout> rtDummyGlobalPipelineLayout;
std::unique_ptr<RenderPipelineLayout> rtDummyLocalPipelineLayout;
std::unique_ptr<D3D12DescriptorHeapAllocator> viewHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> samplerHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
std::unique_ptr<D3D12Pool> customUploadPool;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
uint64_t timestampFrequency = 1;
bool gpuUploadHeapFallback = false;
D3D12Device(D3D12Interface *renderInterface, const std::string &preferredDeviceName);
~D3D12Device() override;
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
std::unique_ptr<RenderCommandFence> createCommandFence() override;
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void waitIdle() const override;
void release();
bool isValid() const;
};
struct D3D12Interface : RenderInterface {
IDXGIFactory4 *dxgiFactory = nullptr;
RenderInterfaceCapabilities capabilities;
std::vector<std::string> deviceNames;
D3D12Interface();
~D3D12Interface() override;
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
const RenderInterfaceCapabilities &getCapabilities() const override;
const std::vector<std::string> &getDeviceNames() const override;
bool isValid() const;
};
};

View file

@ -1,262 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include <climits>
#include "plume_render_interface_types.h"
namespace plume {
// Interfaces.
struct RenderBufferFormattedView {
virtual ~RenderBufferFormattedView() { }
};
struct RenderBuffer {
virtual ~RenderBuffer() { }
virtual void *map(uint32_t subresource = 0, const RenderRange *readRange = nullptr) = 0;
virtual void unmap(uint32_t subresource = 0, const RenderRange *writtenRange = nullptr) = 0;
virtual std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) = 0;
virtual void setName(const std::string &name) = 0;
virtual uint64_t getDeviceAddress() const = 0;
// Concrete implementation shortcuts.
inline RenderBufferReference at(uint64_t offset) const {
return RenderBufferReference(this, offset);
}
};
struct RenderTextureView {
virtual ~RenderTextureView() { }
};
struct RenderTexture {
virtual ~RenderTexture() { }
virtual std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) = 0;
virtual void setName(const std::string &name) = 0;
};
struct RenderAccelerationStructure {
virtual ~RenderAccelerationStructure() { }
};
struct RenderShader {
virtual ~RenderShader() { }
};
struct RenderSampler {
virtual ~RenderSampler() { }
};
struct RenderPipeline {
virtual ~RenderPipeline() { }
virtual void setName(const std::string& name) const = 0;
virtual RenderPipelineProgram getProgram(const std::string &name) const = 0;
};
struct RenderPipelineLayout {
virtual ~RenderPipelineLayout() { }
};
struct RenderCommandFence {
virtual ~RenderCommandFence() { }
};
struct RenderCommandSemaphore {
virtual ~RenderCommandSemaphore() { }
};
struct RenderDescriptorSet {
// Descriptor indices correspond to the index assuming the descriptor set is one contiguous array. They DO NOT correspond to the bindings, which can be sparse.
// User code should derive these indices on its own by looking at the order the bindings were assigned during set creation along with the descriptor count and
// assume it was all allocated in one contiguous array. This allows efficient mapping between Vulkan and D3D12's descriptor models.
virtual ~RenderDescriptorSet() { }
virtual void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) = 0;
virtual void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) = 0;
virtual void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) = 0;
virtual void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) = 0;
};
struct RenderSwapChain {
virtual ~RenderSwapChain() { }
virtual bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) = 0;
virtual void wait() = 0;
virtual bool resize() = 0;
virtual bool needsResize() const = 0;
virtual void setVsyncEnabled(bool vsyncEnabled) = 0;
virtual bool isVsyncEnabled() const = 0;
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
virtual RenderTexture *getTexture(uint32_t textureIndex) = 0;
virtual uint32_t getTextureCount() const = 0;
virtual bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) = 0;
virtual RenderWindow getWindow() const = 0;
virtual bool isEmpty() const = 0;
// Only valid if displayTiming is enabled in capabilities.
virtual uint32_t getRefreshRate() const = 0;
};
struct RenderFramebuffer {
virtual ~RenderFramebuffer() { }
virtual uint32_t getWidth() const = 0;
virtual uint32_t getHeight() const = 0;
};
struct RenderCommandList {
virtual ~RenderCommandList() { }
virtual void begin() = 0;
virtual void end() = 0;
virtual void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) = 0;
virtual void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0;
virtual void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) = 0;
virtual void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) = 0;
virtual void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) = 0;
virtual void setPipeline(const RenderPipeline *pipeline) = 0;
virtual void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) = 0;
virtual void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
virtual void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
virtual void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
virtual void setIndexBuffer(const RenderIndexBufferView *view) = 0;
virtual void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) = 0;
virtual void setViewports(const RenderViewport *viewports, uint32_t count) = 0;
virtual void setScissors(const RenderRect *scissorRects, uint32_t count) = 0;
virtual void setFramebuffer(const RenderFramebuffer *framebuffer) = 0;
virtual void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) = 0;
virtual void clearColor(uint32_t attachmentIndex = 0, RenderColor colorValue = RenderColor(), const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
virtual void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) = 0;
virtual void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX = 0, uint32_t dstY = 0, uint32_t dstZ = 0, const RenderBox *srcBox = nullptr) = 0;
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr, RenderResolveMode resolveMode = RenderResolveMode::AVERAGE) = 0;
virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0;
virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0;
virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
virtual void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) = 0;
virtual void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) = 0;
// Concrete implementation shortcuts.
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &barrier) {
barriers(stages, &barrier, 1, nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier &barrier) {
barriers(stages, nullptr, 0, &barrier, 1);
}
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &bufferBarrier, const RenderTextureBarrier &textureBarrier) {
barriers(stages, &bufferBarrier, 1, &textureBarrier, 1);
}
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount) {
barriers(stages, bufferBarriers, bufferBarriersCount, nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers) {
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), nullptr, 0);
}
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) {
barriers(stages, nullptr, 0, textureBarriers, textureBarriersCount);
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderTextureBarrier> &textureBarriers) {
barriers(stages, nullptr, 0, textureBarriers.data(), uint32_t(textureBarriers.size()));
}
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers, const std::vector<RenderTextureBarrier> &textureBarriers) {
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), textureBarriers.data(), uint32_t(textureBarriers.size()));
}
inline void setViewports(const RenderViewport &viewport) {
setViewports(&viewport, 1);
}
inline void setScissors(const RenderRect &scissorRect) {
setScissors(&scissorRect, 1);
}
};
struct RenderCommandQueue {
virtual ~RenderCommandQueue() { }
virtual std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) = 0;
virtual void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores = nullptr, uint32_t waitSemaphoreCount = 0, RenderCommandSemaphore **signalSemaphores = nullptr, uint32_t signalSemaphoreCount = 0, RenderCommandFence *signalFence = nullptr) = 0;
virtual void waitForCommandFence(RenderCommandFence *fence) = 0;
// Concrete implementation shortcuts.
inline void executeCommandLists(const RenderCommandList *commandList, RenderCommandFence *signalFence = nullptr) {
executeCommandLists(commandList != nullptr ? &commandList : nullptr, commandList != nullptr ? 1 : 0, nullptr, 0, nullptr, 0, signalFence);
}
};
struct RenderPool {
virtual ~RenderPool() { }
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
};
struct RenderQueryPool {
virtual ~RenderQueryPool() { }
virtual void queryResults() = 0;
virtual const uint64_t *getResults() const = 0;
virtual uint32_t getCount() const = 0;
};
struct RenderDevice {
virtual ~RenderDevice() { }
virtual std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) = 0;
virtual std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) = 0;
virtual std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) = 0;
virtual std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) = 0;
virtual std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline = nullptr) = 0;
virtual std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) = 0;
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
virtual std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) = 0;
virtual std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) = 0;
virtual std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) = 0;
virtual std::unique_ptr<RenderCommandFence> createCommandFence() = 0;
virtual std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() = 0;
virtual std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) = 0;
virtual std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) = 0;
virtual void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
virtual void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
virtual void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) = 0;
virtual const RenderDeviceCapabilities &getCapabilities() const = 0;
virtual const RenderDeviceDescription &getDescription() const = 0;
virtual RenderSampleCounts getSampleCountsSupported(RenderFormat format) const = 0;
virtual void waitIdle() const = 0;
};
struct RenderInterface {
virtual ~RenderInterface() { }
virtual std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName = "") = 0;
virtual const std::vector<std::string> &getDeviceNames() const = 0;
virtual const RenderInterfaceCapabilities &getCapabilities() const = 0;
};
extern void RenderInterfaceTest(RenderInterface *renderInterface);
extern void TestInitialize(RenderInterface* renderInterface, RenderWindow window);
extern void TestDraw();
extern void TestResize();
extern void TestShutdown();
};
#include "plume_render_interface_builders.h"

View file

@ -1,281 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include <unordered_set>
namespace plume {
struct RenderDescriptorSetBuilder {
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
std::vector<RenderDescriptorRange> descriptorRanges;
RenderDescriptorSetDesc descriptorSetDesc;
bool open = false;
uint32_t setIndex = 0;
RenderDescriptorSetBuilder() = default;
void begin() {
assert(!open && "Builder must be closed.");
descriptorSetDesc = RenderDescriptorSetDesc();
samplerPointerVectorList.clear();
descriptorRanges.clear();
open = true;
setIndex = 0;
}
uint32_t addConstantBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::CONSTANT_BUFFER, binding, count, nullptr));
}
uint32_t addFormattedBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::FORMATTED_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteFormattedBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_FORMATTED_BUFFER, binding, count, nullptr));
}
uint32_t addTexture(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::TEXTURE, binding, count, nullptr));
}
uint32_t addReadWriteTexture(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_TEXTURE, binding, count, nullptr));
}
uint32_t addSampler(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, nullptr));
}
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler *immutableSampler) {
assert(immutableSampler != nullptr);
return addImmutableSampler(binding, &immutableSampler);
}
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler **immutableSampler, uint32_t count = 1) {
assert(immutableSampler != nullptr);
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + count));
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, samplerPointerVectorList.back().data()));
}
uint32_t addStructuredBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::STRUCTURED_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteStructuredBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_STRUCTURED_BUFFER, binding, count, nullptr));
}
uint32_t addByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::BYTE_ADDRESS_BUFFER, binding, count, nullptr));
}
uint32_t addReadWriteByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_BYTE_ADDRESS_BUFFER, binding, count, nullptr));
}
uint32_t addAccelerationStructure(uint32_t binding, uint32_t count = 1) {
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::ACCELERATION_STRUCTURE, binding, count, nullptr));
}
uint32_t addRange(const RenderDescriptorRange &range) {
assert(open && "Builder must be open.");
uint32_t returnValue = setIndex;
descriptorRanges.emplace_back(range);
descriptorSetDesc.descriptorRangesCount++;
setIndex += range.count;
return returnValue;
}
void end(bool lastRangeIsBoundless = false, uint32_t boundlessRangeSize = 0) {
assert(open && "Builder must be open.");
descriptorSetDesc.lastRangeIsBoundless = lastRangeIsBoundless;
descriptorSetDesc.boundlessRangeSize = boundlessRangeSize;
descriptorSetDesc.descriptorRanges = descriptorRanges.data();
open = false;
}
std::unique_ptr<RenderDescriptorSet> create(RenderDevice *device) const {
assert(!open && "Builder must be closed.");
return device->createDescriptorSet(descriptorSetDesc);
}
};
struct RenderDescriptorSetBase {
RenderDescriptorSetBuilder builder;
std::unique_ptr<RenderDescriptorSet> descriptorSet;
void create(RenderDevice *device) {
descriptorSet = builder.create(device);
}
RenderDescriptorSet *get() const {
return descriptorSet.get();
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, bufferStructuredView, bufferFormattedView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView &bufferStructuredView) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, &bufferStructuredView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferFormattedView *bufferFormattedView) {
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, nullptr, bufferFormattedView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferStructuredView &bufferStructuredView) {
descriptorSet->setBuffer(descriptorIndex, buffer, 0, &bufferStructuredView);
}
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferFormattedView *bufferFormattedView) {
descriptorSet->setBuffer(descriptorIndex, buffer, 0, nullptr, bufferFormattedView);
}
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, const RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) {
descriptorSet->setTexture(descriptorIndex, texture, textureLayout, textureView);
}
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) {
descriptorSet->setSampler(descriptorIndex, sampler);
}
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) {
descriptorSet->setAccelerationStructure(descriptorIndex, accelerationStructure);
}
};
struct RenderDescriptorSetInclusionFilter {
const uint32_t *bindings = nullptr;
uint32_t bindingsCount = 0;
};
struct RenderPipelineLayoutBuilder {
std::vector<RenderPushConstantRange> pushConstantRanges;
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
std::vector<RenderDescriptorRange> descriptorRanges;
std::vector<RenderDescriptorSetDesc> descriptorSetDescs;
std::vector<uint32_t> descriptorRangeIndexPerSet;
std::vector<RenderRootDescriptorDesc> rootDescriptorDescs;
RenderPipelineLayoutDesc layoutDesc;
bool open = false;
// Start filling the description.
void begin(bool isLocal = false, bool allowInputLayout = false) {
assert(!open && "Builder must be closed.");
layoutDesc = RenderPipelineLayoutDesc();
layoutDesc.isLocal = isLocal;
layoutDesc.allowInputLayout = allowInputLayout;
pushConstantRanges.clear();
samplerPointerVectorList.clear();
descriptorRanges.clear();
descriptorSetDescs.clear();
descriptorRangeIndexPerSet.clear();
rootDescriptorDescs.clear();
open = true;
}
// Returns push constant index.
uint32_t addPushConstant(uint32_t binding, uint32_t set, uint32_t size, RenderShaderStageFlags stageFlags, uint32_t offset = 0) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.pushConstantRangesCount;
pushConstantRanges.emplace_back(RenderPushConstantRange(binding, set, offset, size, stageFlags));
layoutDesc.pushConstantRangesCount++;
return returnValue;
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetDesc &descriptorSetDesc) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.descriptorSetDescsCount;
descriptorRangeIndexPerSet.emplace_back(uint32_t(descriptorRanges.size()));
descriptorSetDescs.emplace_back(descriptorSetDesc);
for (uint32_t j = 0; j < descriptorSetDesc.descriptorRangesCount; j++) {
descriptorRanges.emplace_back(descriptorSetDesc.descriptorRanges[j]);
// Copy the immutable sampler pointers to a local vector list.
if (descriptorRanges.back().immutableSampler != nullptr) {
const RenderSampler **immutableSampler = descriptorRanges.back().immutableSampler;
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + descriptorRanges.back().count));
descriptorRanges.back().immutableSampler = samplerPointerVectorList.back().data();
}
}
layoutDesc.descriptorSetDescsCount++;
return returnValue;
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetBuilder &descriptorSetBuilder) {
return addDescriptorSet(descriptorSetBuilder.descriptorSetDesc);
}
// Returns set index.
uint32_t addDescriptorSet(const RenderDescriptorSetBase &descriptorSetBase) {
return addDescriptorSet(descriptorSetBase.builder);
}
// Returns root descriptor index. D3D12 only.
uint32_t addRootDescriptor(uint32_t shaderRegister, uint32_t registerSpace, RenderRootDescriptorType type) {
assert(open && "Builder must be open.");
uint32_t returnValue = layoutDesc.rootDescriptorDescsCount;
rootDescriptorDescs.emplace_back(shaderRegister, registerSpace, type);
++layoutDesc.rootDescriptorDescsCount;
return returnValue;
}
// Finish the description.
void end() {
assert(open && "Builder must be open.");
if (layoutDesc.pushConstantRangesCount > 0) {
layoutDesc.pushConstantRanges = pushConstantRanges.data();
}
if (layoutDesc.descriptorSetDescsCount > 0) {
for (uint32_t i = 0; i < layoutDesc.descriptorSetDescsCount; i++) {
const uint32_t rangeIndex = descriptorRangeIndexPerSet[i];
descriptorSetDescs[i].descriptorRanges = &descriptorRanges[rangeIndex];
}
layoutDesc.descriptorSetDescs = descriptorSetDescs.data();
}
if (layoutDesc.rootDescriptorDescsCount > 0) {
layoutDesc.rootDescriptorDescs = rootDescriptorDescs.data();
}
open = false;
}
// Create a pipeline layout with the final description.
std::unique_ptr<RenderPipelineLayout> create(RenderDevice *device) const {
assert(!open && "Builder must be closed.");
return device->createPipelineLayout(layoutDesc);
}
};
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,456 +0,0 @@
//
// plume
//
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file for details.
//
#pragma once
#include "plume_render_interface.h"
#include <mutex>
#include <set>
#include <unordered_map>
#include <unordered_set>
#if defined(_WIN64)
#define VK_USE_PLATFORM_WIN32_KHR
#elif defined(__ANDROID__)
#define VK_USE_PLATFORM_ANDROID_KHR
#elif defined(__linux__)
#define VK_USE_PLATFORM_XLIB_KHR
#endif
#include <volk.h>
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnullability-completeness"
#endif
#include <vk_mem_alloc.h>
#ifdef __clang__
#pragma clang diagnostic pop
#endif
namespace plume {
struct VulkanCommandQueue;
struct VulkanDevice;
struct VulkanInterface;
struct VulkanPool;
struct VulkanQueue;
struct VulkanBuffer : RenderBuffer {
VkBuffer vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanPool *pool = nullptr;
VmaAllocation allocation = VK_NULL_HANDLE;
VmaAllocationInfo allocationInfo = {};
RenderBufferDesc desc;
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
VulkanBuffer() = default;
VulkanBuffer(VulkanDevice *device, VulkanPool *pool, const RenderBufferDesc &desc);
~VulkanBuffer() override;
void *map(uint32_t subresource, const RenderRange *readRange) override;
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
void setName(const std::string &name) override;
uint64_t getDeviceAddress() const override;
};
struct VulkanBufferFormattedView : RenderBufferFormattedView {
VkBufferView vk = VK_NULL_HANDLE;
VulkanBuffer *buffer = nullptr;
VulkanBufferFormattedView(VulkanBuffer *buffer, RenderFormat format);
~VulkanBufferFormattedView() override;
};
struct VulkanTexture : RenderTexture {
VkImage vk = VK_NULL_HANDLE;
VkImageView imageView = VK_NULL_HANDLE;
VkFormat imageFormat = VK_FORMAT_UNDEFINED;
VkImageSubresourceRange imageSubresourceRange = {};
VulkanDevice *device = nullptr;
VulkanPool *pool = nullptr;
VmaAllocation allocation = VK_NULL_HANDLE;
VmaAllocationInfo allocationInfo = {};
RenderTextureLayout textureLayout = RenderTextureLayout::UNKNOWN;
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
bool ownership = false;
RenderTextureDesc desc;
VulkanTexture() = default;
VulkanTexture(VulkanDevice *device, VulkanPool *pool, const RenderTextureDesc &desc);
VulkanTexture(VulkanDevice *device, VkImage image);
~VulkanTexture() override;
void createImageView(VkFormat format);
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
void setName(const std::string &name) override;
void fillSubresourceRange();
};
struct VulkanTextureView : RenderTextureView {
VkImageView vk = VK_NULL_HANDLE;
VulkanTexture *texture = nullptr;
VulkanTextureView(VulkanTexture *texture, const RenderTextureViewDesc &desc);
~VulkanTextureView() override;
};
struct VulkanAccelerationStructure : RenderAccelerationStructure {
VkAccelerationStructureKHR vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
VulkanAccelerationStructure(VulkanDevice *device, const RenderAccelerationStructureDesc &desc);
~VulkanAccelerationStructure() override;
};
struct VulkanDescriptorSetLayout {
VkDescriptorSetLayout vk = VK_NULL_HANDLE;
std::vector<VkDescriptorSetLayoutBinding> setBindings;
std::vector<uint32_t> descriptorIndexBases;
std::vector<uint32_t> descriptorBindingIndices;
VulkanDevice *device = nullptr;
VulkanDescriptorSetLayout(VulkanDevice *device, const RenderDescriptorSetDesc &descriptorSetDesc);
~VulkanDescriptorSetLayout();
};
struct VulkanPipelineLayout : RenderPipelineLayout {
VkPipelineLayout vk = VK_NULL_HANDLE;
std::vector<VkPushConstantRange> pushConstantRanges;
std::vector<VulkanDescriptorSetLayout *> descriptorSetLayouts;
VulkanDevice *device = nullptr;
VulkanPipelineLayout(VulkanDevice *device, const RenderPipelineLayoutDesc &desc);
~VulkanPipelineLayout() override;
};
struct VulkanShader : RenderShader {
VkShaderModule vk = VK_NULL_HANDLE;
std::string entryPointName;
VulkanDevice *device = nullptr;
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
VulkanShader(VulkanDevice *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
~VulkanShader() override;
};
struct VulkanSampler : RenderSampler {
VkSampler vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanSampler(VulkanDevice *device, const RenderSamplerDesc &desc);
~VulkanSampler();
};
struct VulkanPipeline : RenderPipeline {
enum class Type {
Unknown,
Compute,
Graphics,
Raytracing
};
VulkanDevice *device = nullptr;
Type type = Type::Unknown;
VulkanPipeline(VulkanDevice *device, Type type);
virtual ~VulkanPipeline() override;
};
struct VulkanComputePipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
VulkanComputePipeline(VulkanDevice *device, const RenderComputePipelineDesc &desc);
~VulkanComputePipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct VulkanGraphicsPipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
VkRenderPass renderPass = VK_NULL_HANDLE;
VulkanGraphicsPipeline(VulkanDevice *device, const RenderGraphicsPipelineDesc &desc);
~VulkanGraphicsPipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
static VkRenderPass createRenderPass(VulkanDevice *device, const VkFormat *renderTargetFormat, uint32_t renderTargetCount, VkFormat depthTargetFormat, VkSampleCountFlagBits sampleCount);
};
struct VulkanRaytracingPipeline : VulkanPipeline {
VkPipeline vk = VK_NULL_HANDLE;
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
uint32_t groupCount = 0;
uint32_t descriptorSetCount = 0;
VulkanRaytracingPipeline(VulkanDevice *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
~VulkanRaytracingPipeline() override;
void setName(const std::string& name) const override;
RenderPipelineProgram getProgram(const std::string &name) const override;
};
struct VulkanDescriptorSet : RenderDescriptorSet {
VkDescriptorSet vk = VK_NULL_HANDLE;
VulkanDescriptorSetLayout *setLayout = nullptr;
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanDescriptorSet(VulkanDevice *device, const RenderDescriptorSetDesc &desc);
~VulkanDescriptorSet() override;
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
void setDescriptor(uint32_t descriptorIndex, const VkDescriptorBufferInfo *bufferInfo, const VkDescriptorImageInfo *imageInfo, const VkBufferView *texelBufferView, void *pNext);
static VkDescriptorPool createDescriptorPool(VulkanDevice *device, const std::unordered_map<VkDescriptorType, uint32_t> &typeCounts, bool lastRangeIsBoundless);
};
struct VulkanSwapChain : RenderSwapChain {
VkSwapchainKHR vk = VK_NULL_HANDLE;
VulkanCommandQueue *commandQueue = nullptr;
VkSurfaceKHR surface = VK_NULL_HANDLE;
RenderWindow renderWindow = {};
uint32_t textureCount = 0;
uint64_t presentCount = 0;
RenderFormat format = RenderFormat::UNKNOWN;
uint32_t width = 0;
uint32_t height = 0;
VkSwapchainCreateInfoKHR createInfo = {};
VkSurfaceFormatKHR pickedSurfaceFormat = {};
VkPresentModeKHR createdPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
std::vector<VulkanTexture> textures;
uint64_t currentPresentId = 0;
bool immediatePresentModeSupported = false;
uint32_t maxFrameLatency = 0;
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
~VulkanSwapChain() override;
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
void wait() override;
bool resize() override;
bool needsResize() const override;
void setVsyncEnabled(bool vsyncEnabled) override;
bool isVsyncEnabled() const override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
RenderTexture *getTexture(uint32_t textureIndex) override;
uint32_t getTextureCount() const override;
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
RenderWindow getWindow() const override;
bool isEmpty() const override;
uint32_t getRefreshRate() const override;
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
void releaseSwapChain();
void releaseImageViews();
};
struct VulkanFramebuffer : RenderFramebuffer {
VulkanDevice *device = nullptr;
VkFramebuffer vk = VK_NULL_HANDLE;
VkRenderPass renderPass = VK_NULL_HANDLE;
std::vector<const VulkanTexture *> colorAttachments;
const VulkanTexture *depthAttachment = nullptr;
bool depthAttachmentReadOnly = false;
uint32_t width = 0;
uint32_t height = 0;
VulkanFramebuffer(VulkanDevice *device, const RenderFramebufferDesc &desc);
~VulkanFramebuffer() override;
uint32_t getWidth() const override;
uint32_t getHeight() const override;
bool contains(const VulkanTexture *attachment) const;
};
struct VulkanQueryPool : RenderQueryPool {
VulkanDevice *device = nullptr;
std::vector<uint64_t> results;
VkQueryPool vk = VK_NULL_HANDLE;
VulkanQueryPool(VulkanDevice *device, uint32_t queryCount);
virtual ~VulkanQueryPool() override;
virtual void queryResults() override;
virtual const uint64_t *getResults() const override;
virtual uint32_t getCount() const override;
};
struct VulkanCommandList : RenderCommandList {
VkCommandBuffer vk = VK_NULL_HANDLE;
VkCommandPool commandPool = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
RenderCommandListType type = RenderCommandListType::UNKNOWN;
const VulkanFramebuffer *targetFramebuffer = nullptr;
const VulkanPipelineLayout *activeComputePipelineLayout = nullptr;
const VulkanPipelineLayout *activeGraphicsPipelineLayout = nullptr;
const VulkanPipelineLayout *activeRaytracingPipelineLayout = nullptr;
VkRenderPass activeRenderPass = VK_NULL_HANDLE;
VulkanCommandList(VulkanDevice *device, RenderCommandListType type);
~VulkanCommandList() override;
void begin() override;
void end() override;
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
void setPipeline(const RenderPipeline *pipeline) override;
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
void setIndexBuffer(const RenderIndexBufferView *view) override;
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
void setViewports(const RenderViewport *viewports, uint32_t count) override;
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
void discardTexture(const RenderTexture* texture) override;
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
void checkActiveRenderPass();
void endActiveRenderPass();
void setDescriptorSet(VkPipelineBindPoint bindPoint, const VulkanPipelineLayout *pipelineLayout, const RenderDescriptorSet *descriptorSet, uint32_t setIndex);
};
struct VulkanCommandFence : RenderCommandFence {
VkFence vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanCommandFence(VulkanDevice *device);
~VulkanCommandFence() override;
};
struct VulkanCommandSemaphore : RenderCommandSemaphore {
VkSemaphore vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanCommandSemaphore(VulkanDevice *device);
~VulkanCommandSemaphore() override;
};
struct VulkanCommandQueue : RenderCommandQueue {
VulkanQueue *queue = nullptr;
VulkanDevice *device = nullptr;
uint32_t familyIndex = 0;
uint32_t queueIndex = 0;
std::unordered_set<VulkanSwapChain *> swapChains;
VulkanCommandQueue(VulkanDevice *device, RenderCommandListType commandListType);
~VulkanCommandQueue() override;
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) override;
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
void waitForCommandFence(RenderCommandFence *fence) override;
};
struct VulkanPool : RenderPool {
VmaPool vk = VK_NULL_HANDLE;
VulkanDevice *device = nullptr;
VulkanPool(VulkanDevice *device, const RenderPoolDesc &desc);
~VulkanPool() override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
};
struct VulkanQueue {
VkQueue vk;
std::unique_ptr<std::mutex> mutex;
std::unordered_set<const VulkanCommandQueue *> virtualQueues;
};
struct VulkanQueueFamily {
std::vector<VulkanQueue> queues;
void add(VulkanCommandQueue *virtualQueue);
void remove(VulkanCommandQueue *virtualQueue);
};
struct VulkanDevice : RenderDevice {
VkDevice vk = VK_NULL_HANDLE;
VulkanInterface *renderInterface = nullptr;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VkPhysicalDeviceProperties physicalDeviceProperties = {};
VmaAllocator allocator = VK_NULL_HANDLE;
uint32_t queueFamilyIndices[3] = {};
std::vector<VulkanQueueFamily> queueFamilies;
RenderDeviceCapabilities capabilities;
RenderDeviceDescription description;
VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {};
VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {};
bool loadStoreOpNoneSupported = false;
VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName);
~VulkanDevice() override;
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
std::unique_ptr<RenderCommandFence> createCommandFence() override;
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
const RenderDeviceCapabilities &getCapabilities() const override;
const RenderDeviceDescription &getDescription() const override;
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
void waitIdle() const override;
void release();
bool isValid() const;
};
struct VulkanInterface : RenderInterface {
VkInstance instance = VK_NULL_HANDLE;
VkApplicationInfo appInfo = {};
RenderInterfaceCapabilities capabilities;
std::vector<std::string> deviceNames;
# if SDL_VULKAN_ENABLED
VulkanInterface(RenderWindow sdlWindow);
# else
VulkanInterface();
# endif
~VulkanInterface() override;
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
const RenderInterfaceCapabilities &getCapabilities() const override;
const std::vector<std::string> &getDeviceNames() const override;
bool isValid() const;
};
};

View file

@ -37,6 +37,7 @@
#include <magic_enum/magic_enum.hpp>
#endif
#define UNLEASHED_RECOMP
#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
#ifdef UNLEASHED_RECOMP_D3D12
@ -1837,7 +1838,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
for (auto& commandList : g_commandLists)
commandList = g_device->createCommandList(RenderCommandListType::DIRECT);
commandList = g_queue->createCommandList();
for (auto& commandFence : g_commandFences)
commandFence = g_device->createCommandFence();
@ -1846,7 +1847,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
queryPool = g_device->createQueryPool(NUM_QUERIES);
g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY);
g_copyCommandList = g_copyQueue->createCommandList();
g_copyCommandFence = g_device->createCommandFence();
uint32_t bufferCount = 2;
@ -2074,23 +2075,21 @@ void Video::WaitForGPU()
{
g_waitForGPUCount++;
if (g_vulkan)
// Wait for all queued frames to finish.
for (size_t i = 0; i < NUM_FRAMES; i++)
{
g_device->waitIdle();
}
else
{
for (size_t i = 0; i < NUM_FRAMES; i++)
if (g_commandListStates[i])
{
if (g_commandListStates[i])
{
g_queue->waitForCommandFence(g_commandFences[i].get());
g_commandListStates[i] = false;
}
g_queue->waitForCommandFence(g_commandFences[i].get());
g_commandListStates[i] = false;
}
g_queue->executeCommandLists(nullptr, g_commandFences[0].get());
g_queue->waitForCommandFence(g_commandFences[0].get());
}
// Execute an empty command list and wait for it to end to guarantee that any remaining presentation has finished.
g_commandLists[0]->begin();
g_commandLists[0]->end();
g_queue->executeCommandLists(g_commandLists[0].get(), g_commandFences[0].get());
g_queue->waitForCommandFence(g_commandFences[0].get());
}
static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
@ -5736,7 +5735,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
{
g_copyCommandList->copyTextureRegion(
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % ddsDesc.numMips, subresourceIndex / ddsDesc.numMips),
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
};

View file

@ -4,7 +4,7 @@
/////////////////////////////////////////////////////////////////////#define PSO_CACHING
//#define PSO_CACHING_CLEANUP
#include "rhi/plume_render_interface.h"
#include <plume_render_interface.h>
#define D3DCLEAR_TARGET 0x1
#define D3DCLEAR_ZBUFFER 0x10

View file

@ -166,6 +166,9 @@ void UpdateChecker::visitWebsite()
#elif defined(__linux__)
std::string command = "xdg-open " + std::string(VISIT_URL) + " &";
std::system(command.c_str());
#elif defined(__APPLE__)
std::string command = "open " + std::string(VISIT_URL) + " &";
std::system(command.c_str());
#else
static_assert(false, "Visit website not implemented for this platform.");
#endif

View file

@ -660,7 +660,7 @@ void KeQueryBasePriorityThread()
uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
{
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->thread.get_id() == std::this_thread::get_id());
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId());
hThread->suspended = true;
hThread->suspended.wait(true);

View file

@ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const
if (!exists)
{
std::string root = "";
std::filesystem::path rootPath;
if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
{
std::u8string savePathU8 = GetSavePath(true).u8string();
root = (const char *)(savePathU8.c_str());
rootPath = GetSavePath(true);
}
else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
{
root = GAME_INSTALL_DIRECTORY "/dlc";
rootPath = GetGamePath() / "dlc";
}
else
{
root = GAME_INSTALL_DIRECTORY;
rootPath = GetGamePath();
}
const std::string root = (const char*)rootPath.u8string().c_str();
XamRegisterContent(*pContentData, root);
std::error_code ec;
std::filesystem::create_directory(std::u8string_view((const char8_t*)(root.c_str())), ec);
std::filesystem::create_directory(rootPath, ec);
XamRootCreate(szRootName, root);
}

View file

@ -1,5 +1,7 @@
#include <stdafx.h>
#ifdef __x86_64__
#include <cpuid.h>
#endif
#include <cpu/guest_thread.h>
#include <gpu/video.h>
#include <kernel/function.h>
@ -69,8 +71,10 @@ void KiSystemStartup()
const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update");
const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str();
const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str();
XamRegisterContent(gameContent, gamePath);
XamRegisterContent(updateContent, updatePath);
const auto saveFilePath = GetSaveFilePath(true);
bool saveFileExists = std::filesystem::exists(saveFilePath);
@ -102,7 +106,7 @@ void KiSystemStartup()
XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
std::error_code ec;
for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec))
for (auto& file : std::filesystem::directory_iterator(GetGamePath() / "dlc", ec))
{
if (file.is_directory())
{
@ -165,10 +169,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path)
return entry;
}
#ifdef __x86_64__
__attribute__((constructor(101), target("no-avx,no-avx2"), noinline))
void init()
{
#ifdef __x86_64__
uint32_t eax, ebx, ecx, edx;
// Execute CPUID for processor info and feature bits.
@ -185,8 +189,8 @@ void init()
std::_Exit(1);
}
#endif
}
#endif
int main(int argc, char *argv[])
{
@ -232,7 +236,7 @@ int main(int argc, char *argv[])
{
// Set the current working directory to the executable's path.
std::error_code ec;
std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec);
std::filesystem::current_path(os::process::GetExecutableRoot(), ec);
}
Config::Load();
@ -321,7 +325,7 @@ int main(int argc, char *argv[])
HostStartup();
std::filesystem::path modulePath;
bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath);
bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath);
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
if (runInstallerWizard)
{
@ -331,7 +335,7 @@ int main(int argc, char *argv[])
std::_Exit(1);
}
if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller))
{
std::_Exit(0);
}

View file

@ -100,7 +100,7 @@ void ModLoader::Init()
{
configIni = {};
if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini"))
if (!configIni.read(GetGamePath() / "cpkredir.ini"))
return;
}

View file

@ -15,6 +15,11 @@ std::filesystem::path os::process::GetExecutablePath()
}
}
std::filesystem::path os::process::GetExecutableRoot()
{
return GetExecutablePath().remove_filename();
}
std::filesystem::path os::process::GetWorkingDirectory()
{
char cwd[PATH_MAX] = {};

View file

@ -0,0 +1,17 @@
#include <os/logger.h>
void os::logger::Init()
{
}
void os::logger::Log(const std::string_view str, ELogType type, const char* func)
{
if (func)
{
fmt::println("[{}] {}", func, str);
}
else
{
fmt::println("{}", str);
}
}

View file

@ -0,0 +1,7 @@
#include <os/media.h>
bool os::media::IsExternalMediaPlaying()
{
// This functionality is not supported in macOS.
return false;
}

View file

@ -0,0 +1,97 @@
#include <os/process.h>
#include <CoreFoundation/CFBundle.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
#include <signal.h>
#include <sys/param.h>
#include <unistd.h>
std::filesystem::path os::process::GetExecutablePath()
{
uint32_t exePathSize = PATH_MAX;
char exePath[PATH_MAX] = {};
if (_NSGetExecutablePath(exePath, &exePathSize) == 0)
{
return std::filesystem::path(std::u8string_view((const char8_t*)(exePath)));
}
else
{
return std::filesystem::path();
}
}
std::filesystem::path os::process::GetExecutableRoot()
{
std::filesystem::path resultPath = GetExecutablePath().remove_filename();
if (CFBundleRef bundleRef = CFBundleGetMainBundle())
{
if (CFURLRef bundleUrlRef = CFBundleCopyBundleURL(bundleRef))
{
char appBundlePath[MAXPATHLEN];
if (CFURLGetFileSystemRepresentation(bundleUrlRef, true, (uint8_t*)(appBundlePath), sizeof(appBundlePath)))
{
resultPath = std::filesystem::path(appBundlePath).parent_path();
}
CFRelease(bundleUrlRef);
}
}
return resultPath;
}
std::filesystem::path os::process::GetWorkingDirectory()
{
char cwd[PATH_MAX] = {};
char *res = getcwd(cwd, sizeof(cwd));
if (res != nullptr)
{
return std::filesystem::path(std::u8string_view((const char8_t*)(cwd)));
}
else
{
return std::filesystem::path();
}
}
bool os::process::SetWorkingDirectory(const std::filesystem::path& path)
{
return chdir(path.c_str()) == 0;
}
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
{
pid_t pid = fork();
if (pid < 0)
return false;
if (pid == 0)
{
setsid();
std::u8string workU8 = work.u8string();
chdir((const char*)(workU8.c_str()));
std::u8string pathU8 = path.u8string();
std::vector<char*> argStrs;
argStrs.push_back((char*)(pathU8.c_str()));
for (const std::string& arg : args)
argStrs.push_back((char *)(arg.c_str()));
argStrs.push_back(nullptr);
execvp((const char*)(pathU8.c_str()), argStrs.data());
raise(SIGKILL);
}
return true;
}
void os::process::CheckConsole()
{
// Always visible on macOS.
g_consoleVisible = true;
}
void os::process::ShowConsole()
{
// Unnecessary on macOS.
}

View file

@ -0,0 +1,21 @@
#include <os/registry.h>
// TODO: Implement
inline bool os::registry::Init()
{
return false;
}
// TODO: read from file?
template<typename T>
bool os::registry::ReadValue(const std::string_view& name, T& data)
{
return false;
}
// TODO: write to file?
template<typename T>
bool os::registry::WriteValue(const std::string_view& name, const T& data)
{
return false;
}

View file

@ -0,0 +1,6 @@
#include <os/user.h>
bool os::user::IsDarkTheme()
{
return false;
}

View file

@ -0,0 +1,7 @@
#include <os/version.h>
os::version::OSVersion os::version::GetOSVersion()
{
assert(false && "Unimplemented.");
return os::version::OSVersion();
}

View file

@ -5,6 +5,7 @@ namespace os::process
inline bool g_consoleVisible;
std::filesystem::path GetExecutablePath();
std::filesystem::path GetExecutableRoot();
std::filesystem::path GetWorkingDirectory();
bool SetWorkingDirectory(const std::filesystem::path& path);
bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});

View file

@ -15,4 +15,6 @@ namespace os::registry
#include <os/win32/registry_win32.inl>
#elif defined(__linux__)
#include <os/linux/registry_linux.inl>
#elif defined(__APPLE__)
#include <os/macos/registry_macos.inl>
#endif

View file

@ -10,6 +10,11 @@ std::filesystem::path os::process::GetExecutablePath()
return std::filesystem::path(exePath);
}
std::filesystem::path os::process::GetExecutableRoot()
{
return GetExecutablePath().remove_filename();
}
std::filesystem::path os::process::GetWorkingDirectory()
{
WCHAR workPath[MAX_PATH];

View file

@ -64,6 +64,30 @@ bool UseAlternateTitleMidAsmHook()
return isSWA;
}
bool UseAlternateTitleStaffRollMidAsmHook(PPCRegister& r1)
{
auto pGroupName = (Hedgehog::Base::CSharedString*)g_memory.Translate(r1.s64 + 0x60);
if (Config::UseAlternateTitle)
{
// Redirect English title to Japanese title.
if (strcmp(pGroupName->c_str(), "OFCI5") == 0 || strcmp(pGroupName->c_str(), "OTLR11") == 0)
return Config::Language == ELanguage::Japanese;
// Redirect Japanese title to English title.
if (strcmp(pGroupName->c_str(), "JFCI7") == 0 || strcmp(pGroupName->c_str(), "JTLR13") == 0)
return Config::Language != ELanguage::Japanese;
}
if (pGroupName->c_str()[0] == 'J')
return Config::Language == ELanguage::Japanese;
if (pGroupName->c_str()[0] == 'O')
return Config::Language != ELanguage::Japanese;
return true;
}
/* Hook function that gets the game region
and force result to zero for Japanese
to display the correct logos. */

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>LSMinimumSystemVersion</key>
<string>13.0</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>GCSupportsGameMode</key>
<true/>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

Binary file not shown.

View file

@ -20,7 +20,7 @@ std::unique_ptr<GuestTexture> g_upKBMIcons;
float g_sideMargins = DEFAULT_SIDE_MARGINS;
std::vector<Button> g_buttons;
static std::vector<Button> g_buttons;
std::unordered_map<EButtonIcon, float> g_iconWidths =
{

View file

@ -217,6 +217,9 @@ void GameWindow::Init(const char* sdlVideoDriver)
s_renderWindow = s_pWindow;
#elif defined(__linux__)
s_renderWindow = { info.info.x11.display, info.info.x11.window };
#elif defined(__APPLE__)
s_renderWindow.window = info.info.cocoa.window;
s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow));
#else
static_assert(false, "Unknown platform.");
#endif

View file

@ -1,6 +1,6 @@
#pragma once
#include <gpu/rhi/plume_render_interface_types.h>
#include <plume_render_interface_types.h>
#include <user/config.h>
#include <sdl_events.h>

View file

@ -1146,7 +1146,11 @@ static void PickerStart(bool folderMode) {
g_currentPickerVisible = true;
// Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
#ifdef __APPLE__
constexpr bool singleThreadMode = true;
#else
constexpr bool singleThreadMode = false;
#endif
if (singleThreadMode)
PickerThreadProcess();
else

View file

@ -41,7 +41,7 @@ static ImFont* g_fntSeurat;
std::string g_text;
int g_result;
std::vector<std::string> g_buttons;
static std::vector<std::string> g_buttons;
int g_defaultButtonIndex;
int g_cancelButtonIndex;

View file

@ -1,7 +1,7 @@
#include "paths.h"
#include <os/process.h>
std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename();
std::filesystem::path g_executableRoot = os::process::GetExecutableRoot();
std::filesystem::path g_userPath = BuildUserPath();
bool CheckPortable()
@ -22,18 +22,24 @@ std::filesystem::path BuildUserPath()
userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY;
CoTaskMemFree(knownPath);
#elif defined(__linux__)
#elif defined(__linux__) || defined(__APPLE__)
const char* homeDir = getenv("HOME");
#if defined(__linux__)
if (homeDir == nullptr)
{
homeDir = getpwuid(getuid())->pw_dir;
}
#endif
if (homeDir != nullptr)
{
// Prefer to store in the .config directory if it exists. Use the home directory otherwise.
std::filesystem::path homePath = homeDir;
#if defined(__linux__)
std::filesystem::path configPath = homePath / ".config";
#else
std::filesystem::path configPath = homePath / "Library" / "Application Support";
#endif
if (std::filesystem::exists(configPath))
userPath = configPath / USER_DIRECTORY;
else

View file

@ -10,15 +10,22 @@
extern std::filesystem::path g_executableRoot;
inline std::filesystem::path GetGamePath()
{
return GAME_INSTALL_DIRECTORY;
}
bool CheckPortable();
std::filesystem::path BuildUserPath();
const std::filesystem::path& GetUserPath();
inline std::filesystem::path GetGamePath()
{
#ifdef __APPLE__
// On macOS, there is the expectation that the app may be installed to
// /Applications/, and the bundle should not be modified. Thus we need
// to install game files to the user directory instead of next to the app.
return GetUserPath();
#else
return GAME_INSTALL_DIRECTORY;
#endif
}
inline std::filesystem::path GetSavePath(bool checkForMods)
{
if (checkForMods && !ModLoader::s_saveFilePath.empty())

View file

@ -35,6 +35,7 @@ add_custom_command(
"${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex"
"${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp"
"${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml"
USES_TERMINAL
)
add_custom_command(
@ -53,6 +54,7 @@ target_compile_definitions(XenosRecomp PRIVATE
XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"
XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\"
XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\"
UNLEASHED_RECOMP
)
file(GLOB XENOS_RECOMP_SOURCES
@ -70,6 +72,7 @@ add_custom_command(
"${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"
${XENOS_RECOMP_SOURCES}
${XENOS_RECOMP_INCLUDE}
USES_TERMINAL
)
add_library(UnleashedRecompLib
@ -79,4 +82,5 @@ add_library(UnleashedRecompLib
)
target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(UnleashedRecompLib PRIVATE "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenonRecomp/thirdparty/simde")
target_precompile_headers(UnleashedRecompLib PUBLIC "ppc/ppc_recomp_shared.h")

View file

@ -1101,12 +1101,35 @@ name = "ObjGrindDashPanelAllocMidAsmHook"
address = 0x82614948
registers = ["r3"]
# Title screen logo
[[midasm_hook]]
name = "UseAlternateTitleMidAsmHook"
address = 0x82580F44
jump_address_on_true = 0x82580F48
jump_address_on_false = 0x82580FA0
# Advertise movie logo
[[midasm_hook]]
name = "UseAlternateTitleMidAsmHook"
address = 0x82B73780
jump_address_on_true = 0x82B73784
jump_address_on_false = 0x82B737F8
# Opening movie logo
[[midasm_hook]]
name = "UseAlternateTitleMidAsmHook"
address = 0x82B73630
jump_address_on_true = 0x82B73634
jump_address_on_false = 0x82B736B0
# Staff roll logo
[[midasm_hook]]
name = "UseAlternateTitleStaffRollMidAsmHook"
address = 0x8257EBF0
registers = ["r1"]
jump_address_on_true = 0x8257EC7C
jump_address_on_false = 0x8257ECC0
[[midasm_hook]]
name = "EndingTextAllocMidAsmHook"
address = 0x8257E284

View file

@ -50,6 +50,21 @@ You can also find the equivalent packages for your preferred distro.
> [!NOTE]
> This list may not be comprehensive for your particular distro and you may be required to install additional packages, should an error occur during configuration.
### macOS
You will need to install Xcode 16.3+ or the equivalent Xcode Command Line Tools from Apple.
The following commands will install additional required dependencies, depending on which package manager you use.
If you use Homebrew:
```bash
brew install cmake ninja pkg-config
```
If you use MacPorts:
```bash
sudo port install cmake ninja pkg-config
```
## 4. Build the Project
### Windows
@ -81,3 +96,22 @@ cmake --build ./out/build/linux-release --target UnleashedRecomp
```bash
./UnleashedRecomp
```
### macOS
1. Configure the project using CMake by navigating to the repository and running the following command.
```bash
cmake . --preset macos-release
```
> [!NOTE]
> The available presets are `macos-debug`, `macos-relwithdebinfo` and `macos-release`.
2. Build the project using the selected configuration.
```bash
cmake --build ./out/build/macos-release --target UnleashedRecomp
```
3. Navigate to the directory that was specified as the output in the previous step and run the game.
```bash
open -a UnleashedRecomp.app
```

View file

@ -20,3 +20,8 @@ add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/nativefiledialog-extended"
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/o1heap")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/SDL_mixer")
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume")
if (APPLE)
add_subdirectory("${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/MoltenVK")
endif()

@ -1 +0,0 @@
Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f

86
thirdparty/MoltenVK/CMakeLists.txt vendored Normal file
View file

@ -0,0 +1,86 @@
# Simple CMake script to compile MoltenVK with SPIRV-Cross as a shared library target
# Prepare MoltenVK Git revision
find_package(Git)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
OUTPUT_VARIABLE MVK_GIT_REV
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
set(MVK_GENERATED_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/Generated)
file(WRITE ${MVK_GENERATED_INCLUDES}/mvkGitRevDerived.h "static const char* mvkRevString = \"${MVK_GIT_REV}\";")
message(STATUS "MoltenVK revision: ${MVK_GIT_REV}")
# Prepare MoltenVK version
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/MoltenVK/API/mvk_private_api.h MVK_PRIVATE_API)
string(REGEX MATCH "#define MVK_VERSION_MAJOR [0-9]+" MVK_VERSION_MAJOR_LINE "${MVK_PRIVATE_API}")
string(REGEX MATCH "[0-9]+" MVK_VERSION_MAJOR "${MVK_VERSION_MAJOR_LINE}")
string(REGEX MATCH "#define MVK_VERSION_MINOR [0-9]+" MVK_VERSION_MINOR_LINE "${MVK_PRIVATE_API}")
string(REGEX MATCH "[0-9]+" MVK_VERSION_MINOR "${MVK_VERSION_MINOR_LINE}")
string(REGEX MATCH "#define MVK_VERSION_PATCH [0-9]+" MVK_VERSION_PATCH_LINE "${MVK_PRIVATE_API}")
string(REGEX MATCH "[0-9]+" MVK_VERSION_PATCH "${MVK_VERSION_PATCH_LINE}")
set(MVK_VERSION "${MVK_VERSION_MAJOR}.${MVK_VERSION_MINOR}.${MVK_VERSION_PATCH}")
message(STATUS "MoltenVK version: ${MVK_VERSION}")
# Find required system libraries
find_library(APPKIT_LIBRARY AppKit REQUIRED)
find_library(FOUNDATION_LIBRARY Foundation REQUIRED)
find_library(IOKIT_LIBRARY IOKit REQUIRED)
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
find_library(METAL_LIBRARY Metal REQUIRED)
find_library(QUARTZCORE_LIBRARY QuartzCore REQUIRED)
# SPIRV-Cross
option(SPIRV_CROSS_CLI "" OFF)
option(SPIRV_CROSS_ENABLE_TESTS "" OFF)
option(SPIRV_CROSS_ENABLE_HLSL "" OFF)
option(SPIRV_CROSS_ENABLE_CPP "" OFF)
option(SPIRV_CROSS_SKIP_INSTALL "" ON)
add_subdirectory(SPIRV-Cross)
# Common
set(MVK_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Common)
file(GLOB_RECURSE MVK_COMMON_SOURCES CONFIGURE_DEPENDS
${MVK_COMMON_DIR}/*.cpp
${MVK_COMMON_DIR}/*.m
${MVK_COMMON_DIR}/*.mm)
set(MVK_COMMON_INCLUDES ${MVK_COMMON_DIR})
add_library(MoltenVKCommon STATIC ${MVK_COMMON_SOURCES})
target_include_directories(MoltenVKCommon PUBLIC ${MVK_COMMON_INCLUDES})
target_compile_options(MoltenVKCommon PRIVATE -w)
# MoltenVKShaderConverter
set(MVK_SHADER_CONVERTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKShaderConverter)
file(GLOB_RECURSE MVK_SHADER_CONVERTER_SOURCES CONFIGURE_DEPENDS
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.cpp
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.m
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.mm)
set(MVK_SHADER_CONVERTER_INCLUDES ${MVK_SHADER_CONVERTER_DIR} ${MVK_SHADER_CONVERTER_DIR}/include)
add_library(MoltenVKShaderConverter STATIC ${MVK_SHADER_CONVERTER_SOURCES})
target_include_directories(MoltenVKShaderConverter PUBLIC ${MVK_SHADER_CONVERTER_INCLUDES})
target_compile_options(MoltenVKShaderConverter PRIVATE -w)
target_link_libraries(MoltenVKShaderConverter PRIVATE spirv-cross-msl spirv-cross-reflect MoltenVKCommon)
target_compile_definitions(MoltenVKShaderConverter PRIVATE MVK_EXCLUDE_SPIRV_TOOLS=1)
# MoltenVK
set(MVK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK)
file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS
${MVK_DIR}/MoltenVK/*.cpp
${MVK_DIR}/MoltenVK/*.m
${MVK_DIR}/MoltenVK/*.mm)
file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*)
set(MVK_INCLUDES
${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include
${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume/contrib/Vulkan-Headers/include)
add_library(MoltenVK SHARED ${MVK_SOURCES})
target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES})
target_compile_options(MoltenVK PRIVATE -w)
target_link_libraries(MoltenVK PRIVATE
${APPKIT_LIBRARY} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY}
spirv-cross-msl MoltenVKCommon MoltenVKShaderConverter)
target_compile_definitions(MoltenVK PRIVATE MVK_FRAMEWORK_VERSION=${MVK_VERSION} MVK_USE_CEREAL=0)

1
thirdparty/MoltenVK/MoltenVK vendored Submodule

@ -0,0 +1 @@
Subproject commit 3a0b07a24a4a681ffe70b461b1f4333b2729e2ef

1
thirdparty/MoltenVK/SPIRV-Cross vendored Submodule

@ -0,0 +1 @@
Subproject commit 22b22f5685d868828be01c9ac00c31902e60afd9

@ -1 +0,0 @@
Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7

@ -1 +0,0 @@
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39

1
thirdparty/plume vendored Submodule

@ -0,0 +1 @@
Subproject commit fffeb35f836d8c945697ec82b735e77db401e2de

1
thirdparty/volk vendored

@ -1 +0,0 @@
Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f

@ -1 +1 @@
Subproject commit c017eb630ab917bffd3bc6a0a46995b49e7d8049
Subproject commit c5bfd90d87f2ed0db8cff5c19ea3aff0e161e527

@ -1 +1 @@
Subproject commit 56738e5893ed7c4dc108996590475c52726623e3
Subproject commit 990d03b28a27b50277ee5d8d942e1c5f873869d1

View file

@ -9,8 +9,12 @@
"name": "directx12-agility",
"platform": "windows"
},
"directx-dxc",
"freetype",
"curl"
]
],
"vcpkg-configuration": {
"overlay-triplets": [
"vcpkg/triplets"
]
}
}

View file

@ -0,0 +1,7 @@
set(VCPKG_TARGET_ARCHITECTURE arm64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_OSX_ARCHITECTURES arm64)
set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0")

View file

@ -0,0 +1,7 @@
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
set(VCPKG_OSX_ARCHITECTURES x86_64)
set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0")