mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2025-10-30 07:11:05 +00:00
Compare commits
4 commits
d5de86d53b
...
901654fed1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
901654fed1 | ||
|
|
9ace79a4d2 | ||
|
|
80e779afd9 | ||
|
|
7740f6587d |
59 changed files with 876 additions and 11828 deletions
77
.github/workflows/validate.yml
vendored
77
.github/workflows/validate.yml
vendored
|
|
@ -210,3 +210,80 @@ jobs:
|
|||
with:
|
||||
name: UnleashedRecomp-Flatpak
|
||||
path: ./${{ env.FLATPAK_ID }}.flatpak
|
||||
build-macos:
|
||||
name: Build macOS
|
||||
runs-on: macos-15
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [ "arm64" ]
|
||||
preset: ["macos-debug", "macos-release", "macos-relwithdebinfo"]
|
||||
env:
|
||||
CMAKE_PRESET: ${{ matrix.preset }}
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Checkout Private Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{ secrets.ASSET_REPO }}
|
||||
token: ${{ secrets.ASSET_REPO_TOKEN }}
|
||||
path: ./private
|
||||
|
||||
- name: Setup latest Xcode
|
||||
uses: maxim-lobanov/setup-xcode@v1
|
||||
with:
|
||||
xcode-version: latest-stable
|
||||
|
||||
- name: Setup ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }}
|
||||
|
||||
- name: Cache vcpkg
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
./thirdparty/vcpkg/downloads
|
||||
./thirdparty/vcpkg/packages
|
||||
key: vcpkg-${{ runner.os }}-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }}
|
||||
restore-keys: |
|
||||
vcpkg-${{ runner.os }}-${{ matrix.arch }}-
|
||||
|
||||
- name: Install Dependencies (macOS)
|
||||
run: |
|
||||
brew install ninja
|
||||
|
||||
- name: Cache ccache Directory
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/ccache
|
||||
key: ccache-${{ runner.os }}-${{ matrix.arch }}-${{ matrix.preset }}
|
||||
|
||||
- name: Prepare Project
|
||||
run: |
|
||||
cp ./private/* ./UnleashedRecompLib/private
|
||||
|
||||
- name: Configure Project
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
run: cmake . --preset ${{ env.CMAKE_PRESET }} -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} -DSDL2MIXER_VORBIS=VORBISFILE -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
|
||||
|
||||
- name: Build Project
|
||||
env:
|
||||
CCACHE_DIR: /tmp/ccache
|
||||
run: cmake --build ./out/build/${{ env.CMAKE_PRESET }} --target UnleashedRecomp
|
||||
|
||||
- name: Pack Release
|
||||
run: |
|
||||
codesign --deep -fs - "./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp/Unleashed Recompiled.app"
|
||||
tar -czf UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz -C ./out/build/${{ env.CMAKE_PRESET }}/UnleashedRecomp "Unleashed Recompiled.app"
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}
|
||||
path: UnleashedRecomp-macOS-${{ matrix.arch }}-${{ env.CMAKE_PRESET }}.tar.gz
|
||||
|
|
|
|||
21
.gitmodules
vendored
21
.gitmodules
vendored
|
|
@ -16,21 +16,9 @@
|
|||
[submodule "thirdparty/vcpkg"]
|
||||
path = thirdparty/vcpkg
|
||||
url = https://github.com/microsoft/vcpkg
|
||||
[submodule "thirdparty/volk"]
|
||||
path = thirdparty/volk
|
||||
url = https://github.com/zeux/volk
|
||||
[submodule "thirdparty/SDL"]
|
||||
path = thirdparty/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "thirdparty/Vulkan-Headers"]
|
||||
path = thirdparty/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
[submodule "thirdparty/VulkanMemoryAllocator"]
|
||||
path = thirdparty/VulkanMemoryAllocator
|
||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
[submodule "thirdparty/D3D12MemoryAllocator"]
|
||||
path = thirdparty/D3D12MemoryAllocator
|
||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/D3D12MemoryAllocator.git
|
||||
[submodule "thirdparty/stb"]
|
||||
path = thirdparty/stb
|
||||
url = https://github.com/nothings/stb.git
|
||||
|
|
@ -61,3 +49,12 @@
|
|||
[submodule "UnleashedRecomp/api"]
|
||||
path = UnleashedRecomp/api
|
||||
url = https://github.com/hedge-dev/SWA.git
|
||||
[submodule "thirdparty/MoltenVK/MoltenVK"]
|
||||
path = thirdparty/MoltenVK/MoltenVK
|
||||
url = https://github.com/KhronosGroup/MoltenVK.git
|
||||
[submodule "thirdparty/MoltenVK/SPIRV-Cross"]
|
||||
path = thirdparty/MoltenVK/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross.git
|
||||
[submodule "thirdparty/plume"]
|
||||
path = thirdparty/plume
|
||||
url = https://github.com/renderbag/plume.git
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ if(NOT DEFINED ENV{VCPKG_ROOT})
|
|||
message(FATAL_ERROR "VCPKG_ROOT is not defined!")
|
||||
endif()
|
||||
|
||||
include($ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
|
||||
set(UNLEASHED_RECOMP_THIRDPARTY_ROOT ${CMAKE_SOURCE_DIR}/thirdparty)
|
||||
set(UNLEASHED_RECOMP_TOOLS_ROOT ${CMAKE_SOURCE_DIR}/tools)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
|
@ -18,16 +17,36 @@ endif()
|
|||
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
# Target Sandy Bridge for all projects
|
||||
add_compile_options(
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -113,6 +113,58 @@
|
|||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-base",
|
||||
"hidden": true,
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/out/build/${presetName}",
|
||||
"installDir": "${sourceDir}/out/install/${presetName}",
|
||||
"cacheVariables": {
|
||||
"CMAKE_TOOLCHAIN_FILE": {
|
||||
"value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"type": "FILEPATH"
|
||||
},
|
||||
"CMAKE_OSX_DEPLOYMENT_TARGET": "13.0"
|
||||
},
|
||||
"environment": {
|
||||
"VCPKG_ROOT": "${sourceDir}/thirdparty/vcpkg"
|
||||
},
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Darwin"
|
||||
},
|
||||
"vendor": {
|
||||
"microsoft.com/VisualStudioRemoteSettings/CMake/2.0": {
|
||||
"remoteSourceRootDir": "$env{HOME}/.vs/$ms{projectDirName}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-debug",
|
||||
"displayName": "macOS-Debug",
|
||||
"inherits": "macos-base",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-relwithdebinfo",
|
||||
"displayName": "macOS-RelWithDebInfo",
|
||||
"inherits": "macos-base",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "macos-release",
|
||||
"displayName": "macOS-Release",
|
||||
"inherits": "macos-base",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Release",
|
||||
"CMAKE_INTERPROCEDURAL_OPTIMIZATION": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,6 +97,14 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
|||
"os/linux/user_linux.cpp"
|
||||
"os/linux/version_linux.cpp"
|
||||
)
|
||||
elseif (APPLE)
|
||||
set(UNLEASHED_RECOMP_OS_CXX_SOURCES
|
||||
"os/macos/logger_macos.cpp"
|
||||
"os/macos/media_macos.cpp"
|
||||
"os/macos/process_macos.cpp"
|
||||
"os/macos/user_macos.cpp"
|
||||
"os/macos/version_macos.cpp"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(UNLEASHED_RECOMP_CPU_CXX_SOURCES
|
||||
|
|
@ -108,15 +116,8 @@ 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"
|
||||
|
|
@ -213,18 +214,10 @@ 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
|
||||
|
|
@ -299,6 +292,55 @@ if (WIN32)
|
|||
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()
|
||||
|
|
@ -320,24 +362,22 @@ if (UNLEASHED_RECOMP_D3D12)
|
|||
)
|
||||
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 ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Layers,IMPORTED_LOCATION_DEBUG> $<TARGET_FILE_DIR:UnleashedRecomp>/D3D12
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectXShaderCompiler,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DXIL,IMPORTED_LOCATION> $<TARGET_FILE_DIR:UnleashedRecomp>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
|
||||
find_file(DIRECTX_DXIL_LIBRARY "dxil.dll")
|
||||
file(COPY ${DIRECTX_DXIL_LIBRARY} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
target_link_libraries(UnleashedRecomp PRIVATE
|
||||
Microsoft::DirectX-Headers
|
||||
Microsoft::DirectX-Guids
|
||||
|
|
@ -348,8 +388,6 @@ 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
|
||||
|
|
@ -375,6 +413,7 @@ target_link_libraries(UnleashedRecomp PRIVATE
|
|||
UnleashedRecompLib
|
||||
xxHash::xxhash
|
||||
CURL::libcurl
|
||||
plume
|
||||
)
|
||||
|
||||
target_include_directories(UnleashedRecomp PRIVATE
|
||||
|
|
@ -411,11 +450,11 @@ 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)
|
||||
|
|
|
|||
|
|
@ -40,29 +40,101 @@ GuestThreadContext::~GuestThreadContext()
|
|||
g_userHeap.Free(thread);
|
||||
}
|
||||
|
||||
#ifdef USE_PTHREAD
|
||||
static size_t GetStackSize()
|
||||
{
|
||||
// Cache as this should not change.
|
||||
static size_t stackSize = 0;
|
||||
if (stackSize == 0)
|
||||
{
|
||||
// 8 MiB is a typical default.
|
||||
constexpr auto defaultSize = 8 * 1024 * 1024;
|
||||
struct rlimit lim;
|
||||
const auto ret = getrlimit(RLIMIT_STACK, &lim);
|
||||
if (ret == 0 && lim.rlim_cur < defaultSize)
|
||||
{
|
||||
// Use what the system allows.
|
||||
stackSize = lim.rlim_cur;
|
||||
}
|
||||
else
|
||||
{
|
||||
stackSize = defaultSize;
|
||||
}
|
||||
}
|
||||
return stackSize;
|
||||
}
|
||||
|
||||
static void* GuestThreadFunc(void* arg)
|
||||
{
|
||||
GuestThreadHandle* hThread = (GuestThreadHandle*)arg;
|
||||
#else
|
||||
static void GuestThreadFunc(GuestThreadHandle* hThread)
|
||||
{
|
||||
#endif
|
||||
hThread->suspended.wait(true);
|
||||
GuestThread::Start(hThread->params);
|
||||
#ifdef USE_PTHREAD
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
GuestThreadHandle::GuestThreadHandle(const GuestThreadParams& params)
|
||||
: params(params), suspended((params.flags & 0x1) != 0), thread(GuestThreadFunc, this)
|
||||
: params(params), suspended((params.flags & 0x1) != 0)
|
||||
#ifdef USE_PTHREAD
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, GetStackSize());
|
||||
const auto ret = pthread_create(&thread, &attr, GuestThreadFunc, this);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "pthread_create failed with error code 0x%X.\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
, thread(GuestThreadFunc, this)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
GuestThreadHandle::~GuestThreadHandle()
|
||||
{
|
||||
#ifdef USE_PTHREAD
|
||||
pthread_join(thread, nullptr);
|
||||
#else
|
||||
if (thread.joinable())
|
||||
thread.join();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename ThreadType>
|
||||
static uint32_t CalcThreadId(const ThreadType& id)
|
||||
{
|
||||
if constexpr (sizeof(id) == 4)
|
||||
return *reinterpret_cast<const uint32_t*>(&id);
|
||||
else
|
||||
return XXH32(&id, sizeof(id), 0);
|
||||
}
|
||||
|
||||
uint32_t GuestThreadHandle::GetThreadId() const
|
||||
{
|
||||
#ifdef USE_PTHREAD
|
||||
return CalcThreadId(thread);
|
||||
#else
|
||||
return CalcThreadId(thread.get_id());
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t GuestThreadHandle::Wait(uint32_t timeout)
|
||||
{
|
||||
assert(timeout == INFINITE);
|
||||
|
||||
#ifdef USE_PTHREAD
|
||||
pthread_join(thread, nullptr);
|
||||
#else
|
||||
if (thread.joinable())
|
||||
thread.join();
|
||||
#endif
|
||||
|
||||
return STATUS_WAIT_0;
|
||||
}
|
||||
|
|
@ -80,27 +152,25 @@ uint32_t GuestThread::Start(const GuestThreadParams& params)
|
|||
return ctx.ppcContext.r3.u32;
|
||||
}
|
||||
|
||||
static uint32_t GetThreadId(const std::thread::id& id)
|
||||
{
|
||||
if constexpr (sizeof(id) == 4)
|
||||
return *reinterpret_cast<const uint32_t*>(&id);
|
||||
else
|
||||
return XXH32(&id, sizeof(id), 0);
|
||||
}
|
||||
|
||||
GuestThreadHandle* GuestThread::Start(const GuestThreadParams& params, uint32_t* threadId)
|
||||
{
|
||||
auto hThread = CreateKernelObject<GuestThreadHandle>(params);
|
||||
|
||||
if (threadId != nullptr)
|
||||
*threadId = GetThreadId(hThread->thread.get_id());
|
||||
{
|
||||
*threadId = hThread->GetThreadId();
|
||||
}
|
||||
|
||||
return hThread;
|
||||
}
|
||||
|
||||
uint32_t GuestThread::GetCurrentThreadId()
|
||||
{
|
||||
return GetThreadId(std::this_thread::get_id());
|
||||
#ifdef USE_PTHREAD
|
||||
return CalcThreadId(pthread_self());
|
||||
#else
|
||||
return CalcThreadId(std::this_thread::get_id());
|
||||
#endif
|
||||
}
|
||||
|
||||
void GuestThread::SetLastError(uint32_t error)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,15 @@
|
|||
|
||||
#include <kernel/xdm.h>
|
||||
|
||||
// Use pthreads directly on macOS to be able to increase default stack size.
|
||||
#ifdef __APPLE__
|
||||
#define USE_PTHREAD 1
|
||||
#endif
|
||||
|
||||
#ifdef USE_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#define CURRENT_THREAD_HANDLE uint32_t(-2)
|
||||
|
||||
struct GuestThreadContext
|
||||
|
|
@ -24,11 +33,17 @@ struct GuestThreadHandle : KernelObject
|
|||
{
|
||||
GuestThreadParams params;
|
||||
std::atomic<bool> suspended;
|
||||
#ifdef USE_PTHREAD
|
||||
pthread_t thread;
|
||||
#else
|
||||
std::thread thread;
|
||||
#endif
|
||||
|
||||
GuestThreadHandle(const GuestThreadParams& params);
|
||||
~GuestThreadHandle() override;
|
||||
|
||||
uint32_t GetThreadId() const;
|
||||
|
||||
uint32_t Wait(uint32_t timeout) override;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2024 renderbag and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,481 +0,0 @@
|
|||
//
|
||||
// plume
|
||||
//
|
||||
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file for details.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "plume_render_interface.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <directx/d3d12.h>
|
||||
#include <dxgi1_4.h>
|
||||
|
||||
#include "D3D12MemAlloc.h"
|
||||
|
||||
namespace plume {
|
||||
struct D3D12Buffer;
|
||||
struct D3D12CommandQueue;
|
||||
struct D3D12Device;
|
||||
struct D3D12GraphicsPipeline;
|
||||
struct D3D12Interface;
|
||||
struct D3D12Pipeline;
|
||||
struct D3D12Pool;
|
||||
struct D3D12PipelineLayout;
|
||||
struct D3D12Texture;
|
||||
|
||||
struct D3D12DescriptorHeapAllocator {
|
||||
enum : uint32_t {
|
||||
INVALID_OFFSET = 0xFFFFFFFFU
|
||||
};
|
||||
|
||||
// Reference implementation http://diligentgraphics.com/diligent-engine/architecture/d3d12/variable-size-memory-allocations-manager/
|
||||
struct FreeBlock;
|
||||
|
||||
typedef std::map<uint32_t, FreeBlock> OffsetFreeBlockMap;
|
||||
typedef std::multimap<uint32_t, OffsetFreeBlockMap::iterator> SizeFreeBlockMap;
|
||||
|
||||
struct FreeBlock {
|
||||
uint32_t size;
|
||||
SizeFreeBlockMap::iterator sizeMapIterator;
|
||||
|
||||
FreeBlock(uint32_t size) {
|
||||
this->size = size;
|
||||
}
|
||||
};
|
||||
|
||||
ID3D12DescriptorHeap *heap = nullptr;
|
||||
uint32_t heapSize = 0;
|
||||
uint32_t freeSize = 0;
|
||||
D3D12Device *device = nullptr;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE cpuDescriptorHandle = {};
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE gpuDescriptorHandle = {};
|
||||
UINT descriptorHandleIncrement = 0;
|
||||
OffsetFreeBlockMap offsetFreeBlockMap;
|
||||
SizeFreeBlockMap sizeFreeBlockMap;
|
||||
std::mutex allocationMutex;
|
||||
|
||||
D3D12DescriptorHeapAllocator(D3D12Device *device, uint32_t heapSize, D3D12_DESCRIPTOR_HEAP_TYPE heapType);
|
||||
~D3D12DescriptorHeapAllocator();
|
||||
void addFreeBlock(uint32_t offset, uint32_t size);
|
||||
uint32_t allocate(uint32_t size);
|
||||
void free(uint32_t offset, uint32_t size);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleAt(uint32_t index) const;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE getGPUHandleAt(uint32_t index) const;
|
||||
};
|
||||
|
||||
struct D3D12DescriptorSet : RenderDescriptorSet {
|
||||
D3D12Device *device = nullptr;
|
||||
|
||||
struct HeapAllocation {
|
||||
uint32_t offset = 0;
|
||||
uint32_t count = 0;
|
||||
};
|
||||
|
||||
HeapAllocation viewAllocation;
|
||||
HeapAllocation samplerAllocation;
|
||||
std::vector<RenderDescriptorRangeType> descriptorTypes;
|
||||
std::vector<uint32_t> descriptorHeapIndices;
|
||||
uint32_t descriptorTypeMaxIndex = 0;
|
||||
|
||||
D3D12DescriptorSet(D3D12Device *device, const RenderDescriptorSetDesc &desc);
|
||||
~D3D12DescriptorSet() override;
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
|
||||
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
|
||||
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
|
||||
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
|
||||
void setSRV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *viewDesc);
|
||||
void setUAV(uint32_t descriptorIndex, ID3D12Resource *resource, const D3D12_UNORDERED_ACCESS_VIEW_DESC *viewDesc);
|
||||
void setCBV(uint32_t descriptorIndex, ID3D12Resource *resource, uint64_t bufferSize);
|
||||
};
|
||||
|
||||
struct D3D12SwapChain : RenderSwapChain {
|
||||
IDXGISwapChain3 *d3d = nullptr;
|
||||
HANDLE waitableObject = 0;
|
||||
D3D12CommandQueue *commandQueue = nullptr;
|
||||
RenderWindow renderWindow = {};
|
||||
std::vector<D3D12Texture> textures;
|
||||
uint32_t textureCount = 0;
|
||||
RenderFormat format = RenderFormat::UNKNOWN;
|
||||
DXGI_FORMAT nativeFormat = DXGI_FORMAT_UNKNOWN;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t refreshRate = 0;
|
||||
bool vsyncEnabled = true;
|
||||
uint32_t maxFrameLatency = 0;
|
||||
|
||||
D3D12SwapChain(D3D12CommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
|
||||
~D3D12SwapChain() override;
|
||||
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
|
||||
void wait() override;
|
||||
bool resize() override;
|
||||
bool needsResize() const override;
|
||||
void setVsyncEnabled(bool vsyncEnabled) override;
|
||||
bool isVsyncEnabled() const override;
|
||||
uint32_t getWidth() const override;
|
||||
uint32_t getHeight() const override;
|
||||
RenderTexture *getTexture(uint32_t textureIndex) override;
|
||||
uint32_t getTextureCount() const override;
|
||||
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
|
||||
RenderWindow getWindow() const override;
|
||||
bool isEmpty() const override;
|
||||
uint32_t getRefreshRate() const override;
|
||||
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
|
||||
void setTextures();
|
||||
};
|
||||
|
||||
struct D3D12Framebuffer : RenderFramebuffer {
|
||||
D3D12Device *device = nullptr;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
std::vector<const D3D12Texture *> colorTargets;
|
||||
const D3D12Texture *depthTarget = nullptr;
|
||||
std::vector<D3D12_CPU_DESCRIPTOR_HANDLE> colorHandles;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE depthHandle = {};
|
||||
|
||||
D3D12Framebuffer(D3D12Device *device, const RenderFramebufferDesc &desc);
|
||||
~D3D12Framebuffer() override;
|
||||
uint32_t getWidth() const override;
|
||||
uint32_t getHeight() const override;
|
||||
};
|
||||
|
||||
struct D3D12QueryPool : RenderQueryPool {
|
||||
D3D12Device *device = nullptr;
|
||||
ID3D12QueryHeap *d3d = nullptr;
|
||||
std::vector<uint64_t> results;
|
||||
std::unique_ptr<RenderBuffer> readbackBuffer;
|
||||
|
||||
D3D12QueryPool(D3D12Device *device, uint32_t queryCount);
|
||||
virtual ~D3D12QueryPool() override;
|
||||
virtual void queryResults() override;
|
||||
virtual const uint64_t *getResults() const override;
|
||||
virtual uint32_t getCount() const override;
|
||||
};
|
||||
|
||||
struct D3D12CommandList : RenderCommandList {
|
||||
ID3D12GraphicsCommandList9 *d3d = nullptr;
|
||||
ID3D12CommandAllocator *commandAllocator = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
RenderCommandListType type = RenderCommandListType::UNKNOWN;
|
||||
const D3D12Framebuffer *targetFramebuffer = nullptr;
|
||||
bool targetFramebufferSamplePositionsSet = false;
|
||||
bool open = false;
|
||||
const D3D12PipelineLayout *activeComputePipelineLayout = nullptr;
|
||||
const D3D12PipelineLayout *activeGraphicsPipelineLayout = nullptr;
|
||||
const D3D12GraphicsPipeline *activeGraphicsPipeline = nullptr;
|
||||
bool descriptorHeapsSet = false;
|
||||
D3D12_PRIMITIVE_TOPOLOGY activeTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
bool activeSamplePositions = false;
|
||||
|
||||
D3D12CommandList(D3D12Device *device, RenderCommandListType type);
|
||||
~D3D12CommandList() override;
|
||||
void begin() override;
|
||||
void end() override;
|
||||
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
|
||||
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
|
||||
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
|
||||
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
|
||||
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
|
||||
void setPipeline(const RenderPipeline *pipeline) override;
|
||||
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
|
||||
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setIndexBuffer(const RenderIndexBufferView *view) override;
|
||||
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
|
||||
void setViewports(const RenderViewport *viewports, uint32_t count) override;
|
||||
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
|
||||
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
|
||||
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
|
||||
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
|
||||
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
|
||||
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
|
||||
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
|
||||
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
||||
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
|
||||
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
||||
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
||||
void discardTexture(const RenderTexture* texture) override;
|
||||
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
|
||||
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
|
||||
void checkDescriptorHeaps();
|
||||
void notifyDescriptorHeapWasChangedExternally();
|
||||
void checkTopology();
|
||||
void checkFramebufferSamplePositions();
|
||||
void setSamplePositions(const RenderTexture *texture);
|
||||
void resetSamplePositions();
|
||||
void setDescriptorSet(const D3D12PipelineLayout *activePipelineLayout, RenderDescriptorSet *descriptorSet, uint32_t setIndex, bool setCompute);
|
||||
void setRootDescriptorTable(D3D12DescriptorHeapAllocator *heapAllocator, D3D12DescriptorSet::HeapAllocation &heapAllocation, uint32_t rootIndex, bool setCompute);
|
||||
void setRootDescriptor(const D3D12PipelineLayout *activePipelineLayout, RenderBufferReference bufferReference, uint32_t setIndex, bool setCompute);
|
||||
};
|
||||
|
||||
struct D3D12CommandFence : RenderCommandFence {
|
||||
ID3D12Fence *d3d = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
HANDLE fenceEvent = 0;
|
||||
UINT64 fenceValue = 0;
|
||||
|
||||
D3D12CommandFence(D3D12Device *device);
|
||||
~D3D12CommandFence() override;
|
||||
};
|
||||
|
||||
struct D3D12CommandSemaphore : RenderCommandSemaphore {
|
||||
ID3D12Fence *d3d = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
UINT64 semaphoreValue = 0;
|
||||
|
||||
D3D12CommandSemaphore(D3D12Device *device);
|
||||
~D3D12CommandSemaphore() override;
|
||||
};
|
||||
|
||||
struct D3D12CommandQueue : RenderCommandQueue {
|
||||
ID3D12CommandQueue *d3d = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
RenderCommandListType type = RenderCommandListType::UNKNOWN;
|
||||
|
||||
D3D12CommandQueue(D3D12Device *device, RenderCommandListType type);
|
||||
~D3D12CommandQueue() override;
|
||||
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t newFrameLatency) override;
|
||||
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
|
||||
void waitForCommandFence(RenderCommandFence *fence) override;
|
||||
};
|
||||
|
||||
struct D3D12Buffer : RenderBuffer {
|
||||
ID3D12Resource *d3d = nullptr;
|
||||
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
|
||||
D3D12Device *device = nullptr;
|
||||
D3D12MA::Allocation *allocation = nullptr;
|
||||
D3D12Pool *pool = nullptr;
|
||||
RenderBufferDesc desc;
|
||||
|
||||
D3D12Buffer() = default;
|
||||
D3D12Buffer(D3D12Device *device, D3D12Pool *pool, const RenderBufferDesc &desc);
|
||||
~D3D12Buffer() override;
|
||||
void *map(uint32_t subresource, const RenderRange *readRange) override;
|
||||
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
|
||||
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
|
||||
void setName(const std::string &name) override;
|
||||
uint64_t getDeviceAddress() const override;
|
||||
};
|
||||
|
||||
struct D3D12BufferFormattedView : RenderBufferFormattedView {
|
||||
RenderFormat format = RenderFormat::UNKNOWN;
|
||||
D3D12Buffer *buffer = nullptr;
|
||||
|
||||
D3D12BufferFormattedView(D3D12Buffer *buffer, RenderFormat format);
|
||||
~D3D12BufferFormattedView() override;
|
||||
};
|
||||
|
||||
struct D3D12Texture : RenderTexture {
|
||||
ID3D12Resource *d3d = nullptr;
|
||||
D3D12_RESOURCE_STATES resourceStates = D3D12_RESOURCE_STATE_COMMON;
|
||||
RenderTextureLayout layout = RenderTextureLayout::UNKNOWN;
|
||||
D3D12Device *device = nullptr;
|
||||
D3D12MA::Allocation *allocation = nullptr;
|
||||
D3D12Pool *pool = nullptr;
|
||||
RenderTextureDesc desc;
|
||||
uint32_t targetAllocatorOffset = 0;
|
||||
uint32_t targetEntryCount = 0;
|
||||
bool targetHeapDepth = false;
|
||||
|
||||
D3D12Texture() = default;
|
||||
D3D12Texture(D3D12Device *device, D3D12Pool *pool, const RenderTextureDesc &desc);
|
||||
~D3D12Texture() override;
|
||||
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
|
||||
void setName(const std::string &name) override;
|
||||
void createRenderTargetHeap();
|
||||
void createDepthStencilHeap();
|
||||
void releaseTargetHeap();
|
||||
};
|
||||
|
||||
struct D3D12TextureView : RenderTextureView {
|
||||
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
||||
D3D12Texture *texture = nullptr;
|
||||
RenderTextureViewDimension dimension = RenderTextureViewDimension::UNKNOWN;
|
||||
uint32_t mipLevels = 0;
|
||||
uint32_t mipSlice = 0;
|
||||
uint32_t shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
|
||||
D3D12TextureView(D3D12Texture *texture, const RenderTextureViewDesc &desc);
|
||||
~D3D12TextureView() override;
|
||||
};
|
||||
|
||||
struct D3D12AccelerationStructure :RenderAccelerationStructure {
|
||||
D3D12Device *device = nullptr;
|
||||
const D3D12Buffer *buffer = nullptr;
|
||||
uint64_t offset = 0;
|
||||
uint64_t size = 0;
|
||||
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
|
||||
|
||||
D3D12AccelerationStructure(D3D12Device *device, const RenderAccelerationStructureDesc &desc);
|
||||
~D3D12AccelerationStructure() override;
|
||||
};
|
||||
|
||||
struct D3D12Pool : RenderPool {
|
||||
D3D12MA::Pool *d3d = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
RenderPoolDesc desc;
|
||||
|
||||
D3D12Pool(D3D12Device *device, const RenderPoolDesc &desc, bool gpuUploadHeapFallback);
|
||||
~D3D12Pool() override;
|
||||
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
|
||||
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
|
||||
};
|
||||
|
||||
struct D3D12Shader : RenderShader {
|
||||
const void* data = nullptr;
|
||||
uint64_t size = 0;
|
||||
std::string entryPointName;
|
||||
D3D12Device *device = nullptr;
|
||||
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
|
||||
|
||||
D3D12Shader(D3D12Device *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
|
||||
~D3D12Shader() override;
|
||||
};
|
||||
|
||||
struct D3D12Sampler : RenderSampler {
|
||||
D3D12_SAMPLER_DESC samplerDesc = {};
|
||||
D3D12Device *device = nullptr;
|
||||
RenderBorderColor borderColor = RenderBorderColor::UNKNOWN;
|
||||
RenderShaderVisibility shaderVisibility = RenderShaderVisibility::UNKNOWN;
|
||||
|
||||
D3D12Sampler(D3D12Device *device, const RenderSamplerDesc &desc);
|
||||
~D3D12Sampler() override;
|
||||
};
|
||||
|
||||
struct D3D12Pipeline : RenderPipeline {
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Compute,
|
||||
Graphics,
|
||||
Raytracing
|
||||
};
|
||||
|
||||
D3D12Device *device = nullptr;
|
||||
Type type = Type::Unknown;
|
||||
|
||||
D3D12Pipeline(D3D12Device *device, Type type);
|
||||
virtual ~D3D12Pipeline() override;
|
||||
};
|
||||
|
||||
struct D3D12ComputePipeline : D3D12Pipeline {
|
||||
ID3D12PipelineState *d3d = nullptr;
|
||||
|
||||
D3D12ComputePipeline(D3D12Device *device, const RenderComputePipelineDesc &desc);
|
||||
~D3D12ComputePipeline() override;
|
||||
virtual void setName(const std::string& name) const override;
|
||||
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct D3D12GraphicsPipeline : D3D12Pipeline {
|
||||
ID3D12PipelineState *d3d = nullptr;
|
||||
std::vector<RenderInputSlot> inputSlots;
|
||||
D3D12_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
|
||||
|
||||
D3D12GraphicsPipeline(D3D12Device *device, const RenderGraphicsPipelineDesc &desc);
|
||||
~D3D12GraphicsPipeline() override;
|
||||
virtual void setName(const std::string& name) const override;
|
||||
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct D3D12RaytracingPipeline : D3D12Pipeline {
|
||||
ID3D12StateObject *stateObject = nullptr;
|
||||
ID3D12StateObjectProperties *stateObjectProperties = nullptr;
|
||||
std::vector<void *> programShaderIdentifiers;
|
||||
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
|
||||
const D3D12PipelineLayout *pipelineLayout = nullptr;
|
||||
|
||||
D3D12RaytracingPipeline(D3D12Device *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
|
||||
~D3D12RaytracingPipeline() override;
|
||||
virtual void setName(const std::string& name) const override;
|
||||
virtual RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct D3D12PipelineLayout : RenderPipelineLayout {
|
||||
ID3D12RootSignature *rootSignature = nullptr;
|
||||
D3D12Device *device = nullptr;
|
||||
std::vector<RenderPushConstantRange> pushConstantRanges;
|
||||
std::vector<uint32_t> setViewRootIndices;
|
||||
std::vector<uint32_t> setSamplerRootIndices;
|
||||
std::vector<std::pair<uint32_t, RenderRootDescriptorType>> rootDescriptorRootIndicesAndTypes;
|
||||
uint32_t setCount = 0;
|
||||
uint32_t rootCount = 0;
|
||||
|
||||
D3D12PipelineLayout(D3D12Device *device, const RenderPipelineLayoutDesc &desc);
|
||||
~D3D12PipelineLayout() override;
|
||||
};
|
||||
|
||||
struct D3D12Device : RenderDevice {
|
||||
ID3D12Device8 *d3d = nullptr;
|
||||
D3D12Interface *renderInterface = nullptr;
|
||||
IDXGIAdapter1 *adapter = nullptr;
|
||||
D3D12MA::Allocator *allocator = nullptr;
|
||||
D3D_SHADER_MODEL shaderModel = D3D_SHADER_MODEL(0);
|
||||
std::unique_ptr<RenderPipelineLayout> rtDummyGlobalPipelineLayout;
|
||||
std::unique_ptr<RenderPipelineLayout> rtDummyLocalPipelineLayout;
|
||||
std::unique_ptr<D3D12DescriptorHeapAllocator> viewHeapAllocator;
|
||||
std::unique_ptr<D3D12DescriptorHeapAllocator> samplerHeapAllocator;
|
||||
std::unique_ptr<D3D12DescriptorHeapAllocator> colorTargetHeapAllocator;
|
||||
std::unique_ptr<D3D12DescriptorHeapAllocator> depthTargetHeapAllocator;
|
||||
std::unique_ptr<D3D12Pool> customUploadPool;
|
||||
RenderDeviceCapabilities capabilities;
|
||||
RenderDeviceDescription description;
|
||||
uint64_t timestampFrequency = 1;
|
||||
bool gpuUploadHeapFallback = false;
|
||||
|
||||
D3D12Device(D3D12Interface *renderInterface, const std::string &preferredDeviceName);
|
||||
~D3D12Device() override;
|
||||
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
|
||||
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
|
||||
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
|
||||
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
|
||||
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
|
||||
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
|
||||
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
|
||||
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
|
||||
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
|
||||
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
|
||||
std::unique_ptr<RenderCommandFence> createCommandFence() override;
|
||||
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
|
||||
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
|
||||
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
|
||||
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
|
||||
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
|
||||
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
|
||||
const RenderDeviceCapabilities &getCapabilities() const override;
|
||||
const RenderDeviceDescription &getDescription() const override;
|
||||
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
|
||||
void waitIdle() const override;
|
||||
void release();
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
struct D3D12Interface : RenderInterface {
|
||||
IDXGIFactory4 *dxgiFactory = nullptr;
|
||||
RenderInterfaceCapabilities capabilities;
|
||||
std::vector<std::string> deviceNames;
|
||||
|
||||
D3D12Interface();
|
||||
~D3D12Interface() override;
|
||||
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
|
||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||
const std::vector<std::string> &getDeviceNames() const override;
|
||||
bool isValid() const;
|
||||
};
|
||||
};
|
||||
|
|
@ -1,262 +0,0 @@
|
|||
//
|
||||
// plume
|
||||
//
|
||||
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file for details.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <climits>
|
||||
|
||||
#include "plume_render_interface_types.h"
|
||||
|
||||
namespace plume {
|
||||
// Interfaces.
|
||||
|
||||
struct RenderBufferFormattedView {
|
||||
virtual ~RenderBufferFormattedView() { }
|
||||
};
|
||||
|
||||
struct RenderBuffer {
|
||||
virtual ~RenderBuffer() { }
|
||||
virtual void *map(uint32_t subresource = 0, const RenderRange *readRange = nullptr) = 0;
|
||||
virtual void unmap(uint32_t subresource = 0, const RenderRange *writtenRange = nullptr) = 0;
|
||||
virtual std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) = 0;
|
||||
virtual void setName(const std::string &name) = 0;
|
||||
virtual uint64_t getDeviceAddress() const = 0;
|
||||
|
||||
// Concrete implementation shortcuts.
|
||||
inline RenderBufferReference at(uint64_t offset) const {
|
||||
return RenderBufferReference(this, offset);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderTextureView {
|
||||
virtual ~RenderTextureView() { }
|
||||
};
|
||||
|
||||
struct RenderTexture {
|
||||
virtual ~RenderTexture() { }
|
||||
virtual std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) = 0;
|
||||
virtual void setName(const std::string &name) = 0;
|
||||
};
|
||||
|
||||
struct RenderAccelerationStructure {
|
||||
virtual ~RenderAccelerationStructure() { }
|
||||
};
|
||||
|
||||
struct RenderShader {
|
||||
virtual ~RenderShader() { }
|
||||
};
|
||||
|
||||
struct RenderSampler {
|
||||
virtual ~RenderSampler() { }
|
||||
};
|
||||
|
||||
struct RenderPipeline {
|
||||
virtual ~RenderPipeline() { }
|
||||
virtual void setName(const std::string& name) const = 0;
|
||||
virtual RenderPipelineProgram getProgram(const std::string &name) const = 0;
|
||||
};
|
||||
|
||||
struct RenderPipelineLayout {
|
||||
virtual ~RenderPipelineLayout() { }
|
||||
};
|
||||
|
||||
struct RenderCommandFence {
|
||||
virtual ~RenderCommandFence() { }
|
||||
};
|
||||
|
||||
struct RenderCommandSemaphore {
|
||||
virtual ~RenderCommandSemaphore() { }
|
||||
};
|
||||
|
||||
struct RenderDescriptorSet {
|
||||
// Descriptor indices correspond to the index assuming the descriptor set is one contiguous array. They DO NOT correspond to the bindings, which can be sparse.
|
||||
// User code should derive these indices on its own by looking at the order the bindings were assigned during set creation along with the descriptor count and
|
||||
// assume it was all allocated in one contiguous array. This allows efficient mapping between Vulkan and D3D12's descriptor models.
|
||||
|
||||
virtual ~RenderDescriptorSet() { }
|
||||
virtual void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) = 0;
|
||||
virtual void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) = 0;
|
||||
virtual void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) = 0;
|
||||
virtual void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) = 0;
|
||||
};
|
||||
|
||||
struct RenderSwapChain {
|
||||
virtual ~RenderSwapChain() { }
|
||||
virtual bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) = 0;
|
||||
virtual void wait() = 0;
|
||||
virtual bool resize() = 0;
|
||||
virtual bool needsResize() const = 0;
|
||||
virtual void setVsyncEnabled(bool vsyncEnabled) = 0;
|
||||
virtual bool isVsyncEnabled() const = 0;
|
||||
virtual uint32_t getWidth() const = 0;
|
||||
virtual uint32_t getHeight() const = 0;
|
||||
virtual RenderTexture *getTexture(uint32_t textureIndex) = 0;
|
||||
virtual uint32_t getTextureCount() const = 0;
|
||||
virtual bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) = 0;
|
||||
virtual RenderWindow getWindow() const = 0;
|
||||
virtual bool isEmpty() const = 0;
|
||||
|
||||
// Only valid if displayTiming is enabled in capabilities.
|
||||
virtual uint32_t getRefreshRate() const = 0;
|
||||
};
|
||||
|
||||
struct RenderFramebuffer {
|
||||
virtual ~RenderFramebuffer() { }
|
||||
virtual uint32_t getWidth() const = 0;
|
||||
virtual uint32_t getHeight() const = 0;
|
||||
};
|
||||
|
||||
struct RenderCommandList {
|
||||
virtual ~RenderCommandList() { }
|
||||
virtual void begin() = 0;
|
||||
virtual void end() = 0;
|
||||
virtual void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) = 0;
|
||||
virtual void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) = 0;
|
||||
virtual void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) = 0;
|
||||
virtual void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) = 0;
|
||||
virtual void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) = 0;
|
||||
virtual void setPipeline(const RenderPipeline *pipeline) = 0;
|
||||
virtual void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
|
||||
virtual void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
|
||||
virtual void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
|
||||
virtual void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
|
||||
virtual void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
|
||||
virtual void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
|
||||
virtual void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) = 0;
|
||||
virtual void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) = 0;
|
||||
virtual void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) = 0;
|
||||
virtual void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) = 0;
|
||||
virtual void setIndexBuffer(const RenderIndexBufferView *view) = 0;
|
||||
virtual void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) = 0;
|
||||
virtual void setViewports(const RenderViewport *viewports, uint32_t count) = 0;
|
||||
virtual void setScissors(const RenderRect *scissorRects, uint32_t count) = 0;
|
||||
virtual void setFramebuffer(const RenderFramebuffer *framebuffer) = 0;
|
||||
virtual void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) = 0;
|
||||
virtual void clearColor(uint32_t attachmentIndex = 0, RenderColor colorValue = RenderColor(), const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
|
||||
virtual void clearDepth(bool clearDepth = true, float depthValue = 1.0f, const RenderRect *clearRects = nullptr, uint32_t clearRectsCount = 0) = 0;
|
||||
virtual void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) = 0;
|
||||
virtual void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX = 0, uint32_t dstY = 0, uint32_t dstZ = 0, const RenderBox *srcBox = nullptr) = 0;
|
||||
virtual void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) = 0;
|
||||
virtual void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
||||
virtual void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) = 0;
|
||||
virtual void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect = nullptr, RenderResolveMode resolveMode = RenderResolveMode::AVERAGE) = 0;
|
||||
virtual void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) = 0;
|
||||
virtual void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) = 0;
|
||||
virtual void discardTexture(const RenderTexture* texture) = 0; // D3D12 only.
|
||||
virtual void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) = 0;
|
||||
virtual void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) = 0;
|
||||
|
||||
// Concrete implementation shortcuts.
|
||||
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &barrier) {
|
||||
barriers(stages, &barrier, 1, nullptr, 0);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier &barrier) {
|
||||
barriers(stages, nullptr, 0, &barrier, 1);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier &bufferBarrier, const RenderTextureBarrier &textureBarrier) {
|
||||
barriers(stages, &bufferBarrier, 1, &textureBarrier, 1);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount) {
|
||||
barriers(stages, bufferBarriers, bufferBarriersCount, nullptr, 0);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers) {
|
||||
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), nullptr, 0);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) {
|
||||
barriers(stages, nullptr, 0, textureBarriers, textureBarriersCount);
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const std::vector<RenderTextureBarrier> &textureBarriers) {
|
||||
barriers(stages, nullptr, 0, textureBarriers.data(), uint32_t(textureBarriers.size()));
|
||||
}
|
||||
|
||||
inline void barriers(RenderBarrierStages stages, const std::vector<RenderBufferBarrier> &bufferBarriers, const std::vector<RenderTextureBarrier> &textureBarriers) {
|
||||
barriers(stages, bufferBarriers.data(), uint32_t(bufferBarriers.size()), textureBarriers.data(), uint32_t(textureBarriers.size()));
|
||||
}
|
||||
|
||||
inline void setViewports(const RenderViewport &viewport) {
|
||||
setViewports(&viewport, 1);
|
||||
}
|
||||
|
||||
inline void setScissors(const RenderRect &scissorRect) {
|
||||
setScissors(&scissorRect, 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderCommandQueue {
|
||||
virtual ~RenderCommandQueue() { }
|
||||
virtual std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency) = 0;
|
||||
virtual void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores = nullptr, uint32_t waitSemaphoreCount = 0, RenderCommandSemaphore **signalSemaphores = nullptr, uint32_t signalSemaphoreCount = 0, RenderCommandFence *signalFence = nullptr) = 0;
|
||||
virtual void waitForCommandFence(RenderCommandFence *fence) = 0;
|
||||
|
||||
// Concrete implementation shortcuts.
|
||||
inline void executeCommandLists(const RenderCommandList *commandList, RenderCommandFence *signalFence = nullptr) {
|
||||
executeCommandLists(commandList != nullptr ? &commandList : nullptr, commandList != nullptr ? 1 : 0, nullptr, 0, nullptr, 0, signalFence);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderPool {
|
||||
virtual ~RenderPool() { }
|
||||
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
|
||||
};
|
||||
|
||||
struct RenderQueryPool {
|
||||
virtual ~RenderQueryPool() { }
|
||||
virtual void queryResults() = 0;
|
||||
virtual const uint64_t *getResults() const = 0;
|
||||
virtual uint32_t getCount() const = 0;
|
||||
};
|
||||
|
||||
struct RenderDevice {
|
||||
virtual ~RenderDevice() { }
|
||||
virtual std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) = 0;
|
||||
virtual std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) = 0;
|
||||
virtual std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline = nullptr) = 0;
|
||||
virtual std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) = 0;
|
||||
virtual std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderCommandFence> createCommandFence() = 0;
|
||||
virtual std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() = 0;
|
||||
virtual std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) = 0;
|
||||
virtual std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) = 0;
|
||||
virtual void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
|
||||
virtual void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild = true, bool preferFastTrace = false) = 0;
|
||||
virtual void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) = 0;
|
||||
virtual const RenderDeviceCapabilities &getCapabilities() const = 0;
|
||||
virtual const RenderDeviceDescription &getDescription() const = 0;
|
||||
virtual RenderSampleCounts getSampleCountsSupported(RenderFormat format) const = 0;
|
||||
virtual void waitIdle() const = 0;
|
||||
};
|
||||
|
||||
struct RenderInterface {
|
||||
virtual ~RenderInterface() { }
|
||||
virtual std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName = "") = 0;
|
||||
virtual const std::vector<std::string> &getDeviceNames() const = 0;
|
||||
virtual const RenderInterfaceCapabilities &getCapabilities() const = 0;
|
||||
};
|
||||
|
||||
extern void RenderInterfaceTest(RenderInterface *renderInterface);
|
||||
extern void TestInitialize(RenderInterface* renderInterface, RenderWindow window);
|
||||
extern void TestDraw();
|
||||
extern void TestResize();
|
||||
extern void TestShutdown();
|
||||
};
|
||||
|
||||
#include "plume_render_interface_builders.h"
|
||||
|
|
@ -1,281 +0,0 @@
|
|||
//
|
||||
// plume
|
||||
//
|
||||
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file for details.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
namespace plume {
|
||||
struct RenderDescriptorSetBuilder {
|
||||
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
|
||||
std::vector<RenderDescriptorRange> descriptorRanges;
|
||||
RenderDescriptorSetDesc descriptorSetDesc;
|
||||
bool open = false;
|
||||
uint32_t setIndex = 0;
|
||||
|
||||
RenderDescriptorSetBuilder() = default;
|
||||
|
||||
void begin() {
|
||||
assert(!open && "Builder must be closed.");
|
||||
|
||||
descriptorSetDesc = RenderDescriptorSetDesc();
|
||||
|
||||
samplerPointerVectorList.clear();
|
||||
descriptorRanges.clear();
|
||||
|
||||
open = true;
|
||||
setIndex = 0;
|
||||
}
|
||||
|
||||
uint32_t addConstantBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::CONSTANT_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addFormattedBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::FORMATTED_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addReadWriteFormattedBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_FORMATTED_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addTexture(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::TEXTURE, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addReadWriteTexture(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_TEXTURE, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addSampler(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler *immutableSampler) {
|
||||
assert(immutableSampler != nullptr);
|
||||
|
||||
return addImmutableSampler(binding, &immutableSampler);
|
||||
}
|
||||
|
||||
uint32_t addImmutableSampler(uint32_t binding, const RenderSampler **immutableSampler, uint32_t count = 1) {
|
||||
assert(immutableSampler != nullptr);
|
||||
|
||||
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + count));
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::SAMPLER, binding, count, samplerPointerVectorList.back().data()));
|
||||
}
|
||||
|
||||
uint32_t addStructuredBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::STRUCTURED_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addReadWriteStructuredBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_STRUCTURED_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::BYTE_ADDRESS_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addReadWriteByteAddressBuffer(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::READ_WRITE_BYTE_ADDRESS_BUFFER, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addAccelerationStructure(uint32_t binding, uint32_t count = 1) {
|
||||
return addRange(RenderDescriptorRange(RenderDescriptorRangeType::ACCELERATION_STRUCTURE, binding, count, nullptr));
|
||||
}
|
||||
|
||||
uint32_t addRange(const RenderDescriptorRange &range) {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
uint32_t returnValue = setIndex;
|
||||
descriptorRanges.emplace_back(range);
|
||||
descriptorSetDesc.descriptorRangesCount++;
|
||||
setIndex += range.count;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
void end(bool lastRangeIsBoundless = false, uint32_t boundlessRangeSize = 0) {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
descriptorSetDesc.lastRangeIsBoundless = lastRangeIsBoundless;
|
||||
descriptorSetDesc.boundlessRangeSize = boundlessRangeSize;
|
||||
descriptorSetDesc.descriptorRanges = descriptorRanges.data();
|
||||
open = false;
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderDescriptorSet> create(RenderDevice *device) const {
|
||||
assert(!open && "Builder must be closed.");
|
||||
|
||||
return device->createDescriptorSet(descriptorSetDesc);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderDescriptorSetBase {
|
||||
RenderDescriptorSetBuilder builder;
|
||||
std::unique_ptr<RenderDescriptorSet> descriptorSet;
|
||||
|
||||
void create(RenderDevice *device) {
|
||||
descriptorSet = builder.create(device);
|
||||
}
|
||||
|
||||
RenderDescriptorSet *get() const {
|
||||
return descriptorSet.get();
|
||||
}
|
||||
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize = 0, const RenderBufferStructuredView *bufferStructuredView = nullptr, const RenderBufferFormattedView *bufferFormattedView = nullptr) {
|
||||
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, bufferStructuredView, bufferFormattedView);
|
||||
}
|
||||
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView &bufferStructuredView) {
|
||||
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, &bufferStructuredView);
|
||||
}
|
||||
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferFormattedView *bufferFormattedView) {
|
||||
descriptorSet->setBuffer(descriptorIndex, buffer, bufferSize, nullptr, bufferFormattedView);
|
||||
}
|
||||
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferStructuredView &bufferStructuredView) {
|
||||
descriptorSet->setBuffer(descriptorIndex, buffer, 0, &bufferStructuredView);
|
||||
}
|
||||
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, const RenderBufferFormattedView *bufferFormattedView) {
|
||||
descriptorSet->setBuffer(descriptorIndex, buffer, 0, nullptr, bufferFormattedView);
|
||||
}
|
||||
|
||||
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, const RenderTextureLayout textureLayout, const RenderTextureView *textureView = nullptr) {
|
||||
descriptorSet->setTexture(descriptorIndex, texture, textureLayout, textureView);
|
||||
}
|
||||
|
||||
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) {
|
||||
descriptorSet->setSampler(descriptorIndex, sampler);
|
||||
}
|
||||
|
||||
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) {
|
||||
descriptorSet->setAccelerationStructure(descriptorIndex, accelerationStructure);
|
||||
}
|
||||
};
|
||||
|
||||
struct RenderDescriptorSetInclusionFilter {
|
||||
const uint32_t *bindings = nullptr;
|
||||
uint32_t bindingsCount = 0;
|
||||
};
|
||||
|
||||
struct RenderPipelineLayoutBuilder {
|
||||
std::vector<RenderPushConstantRange> pushConstantRanges;
|
||||
std::list<std::vector<const RenderSampler *>> samplerPointerVectorList;
|
||||
std::vector<RenderDescriptorRange> descriptorRanges;
|
||||
std::vector<RenderDescriptorSetDesc> descriptorSetDescs;
|
||||
std::vector<uint32_t> descriptorRangeIndexPerSet;
|
||||
std::vector<RenderRootDescriptorDesc> rootDescriptorDescs;
|
||||
RenderPipelineLayoutDesc layoutDesc;
|
||||
bool open = false;
|
||||
|
||||
// Start filling the description.
|
||||
void begin(bool isLocal = false, bool allowInputLayout = false) {
|
||||
assert(!open && "Builder must be closed.");
|
||||
|
||||
layoutDesc = RenderPipelineLayoutDesc();
|
||||
layoutDesc.isLocal = isLocal;
|
||||
layoutDesc.allowInputLayout = allowInputLayout;
|
||||
|
||||
pushConstantRanges.clear();
|
||||
samplerPointerVectorList.clear();
|
||||
descriptorRanges.clear();
|
||||
descriptorSetDescs.clear();
|
||||
descriptorRangeIndexPerSet.clear();
|
||||
rootDescriptorDescs.clear();
|
||||
|
||||
open = true;
|
||||
}
|
||||
|
||||
// Returns push constant index.
|
||||
uint32_t addPushConstant(uint32_t binding, uint32_t set, uint32_t size, RenderShaderStageFlags stageFlags, uint32_t offset = 0) {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
uint32_t returnValue = layoutDesc.pushConstantRangesCount;
|
||||
pushConstantRanges.emplace_back(RenderPushConstantRange(binding, set, offset, size, stageFlags));
|
||||
layoutDesc.pushConstantRangesCount++;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// Returns set index.
|
||||
uint32_t addDescriptorSet(const RenderDescriptorSetDesc &descriptorSetDesc) {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
uint32_t returnValue = layoutDesc.descriptorSetDescsCount;
|
||||
descriptorRangeIndexPerSet.emplace_back(uint32_t(descriptorRanges.size()));
|
||||
descriptorSetDescs.emplace_back(descriptorSetDesc);
|
||||
|
||||
for (uint32_t j = 0; j < descriptorSetDesc.descriptorRangesCount; j++) {
|
||||
descriptorRanges.emplace_back(descriptorSetDesc.descriptorRanges[j]);
|
||||
|
||||
// Copy the immutable sampler pointers to a local vector list.
|
||||
if (descriptorRanges.back().immutableSampler != nullptr) {
|
||||
const RenderSampler **immutableSampler = descriptorRanges.back().immutableSampler;
|
||||
samplerPointerVectorList.emplace_back(std::vector<const RenderSampler *>(immutableSampler, immutableSampler + descriptorRanges.back().count));
|
||||
descriptorRanges.back().immutableSampler = samplerPointerVectorList.back().data();
|
||||
}
|
||||
}
|
||||
|
||||
layoutDesc.descriptorSetDescsCount++;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// Returns set index.
|
||||
uint32_t addDescriptorSet(const RenderDescriptorSetBuilder &descriptorSetBuilder) {
|
||||
return addDescriptorSet(descriptorSetBuilder.descriptorSetDesc);
|
||||
}
|
||||
|
||||
// Returns set index.
|
||||
uint32_t addDescriptorSet(const RenderDescriptorSetBase &descriptorSetBase) {
|
||||
return addDescriptorSet(descriptorSetBase.builder);
|
||||
}
|
||||
|
||||
// Returns root descriptor index. D3D12 only.
|
||||
uint32_t addRootDescriptor(uint32_t shaderRegister, uint32_t registerSpace, RenderRootDescriptorType type) {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
uint32_t returnValue = layoutDesc.rootDescriptorDescsCount;
|
||||
rootDescriptorDescs.emplace_back(shaderRegister, registerSpace, type);
|
||||
++layoutDesc.rootDescriptorDescsCount;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// Finish the description.
|
||||
void end() {
|
||||
assert(open && "Builder must be open.");
|
||||
|
||||
if (layoutDesc.pushConstantRangesCount > 0) {
|
||||
layoutDesc.pushConstantRanges = pushConstantRanges.data();
|
||||
}
|
||||
|
||||
if (layoutDesc.descriptorSetDescsCount > 0) {
|
||||
for (uint32_t i = 0; i < layoutDesc.descriptorSetDescsCount; i++) {
|
||||
const uint32_t rangeIndex = descriptorRangeIndexPerSet[i];
|
||||
descriptorSetDescs[i].descriptorRanges = &descriptorRanges[rangeIndex];
|
||||
}
|
||||
|
||||
layoutDesc.descriptorSetDescs = descriptorSetDescs.data();
|
||||
}
|
||||
|
||||
if (layoutDesc.rootDescriptorDescsCount > 0) {
|
||||
layoutDesc.rootDescriptorDescs = rootDescriptorDescs.data();
|
||||
}
|
||||
|
||||
open = false;
|
||||
}
|
||||
|
||||
// Create a pipeline layout with the final description.
|
||||
std::unique_ptr<RenderPipelineLayout> create(RenderDevice *device) const {
|
||||
assert(!open && "Builder must be closed.");
|
||||
|
||||
return device->createPipelineLayout(layoutDesc);
|
||||
}
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,456 +0,0 @@
|
|||
//
|
||||
// plume
|
||||
//
|
||||
// Copyright (c) 2024 renderbag and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file for details.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "plume_render_interface.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#if defined(_WIN64)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR
|
||||
#elif defined(__ANDROID__)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
#elif defined(__linux__)
|
||||
#define VK_USE_PLATFORM_XLIB_KHR
|
||||
#endif
|
||||
|
||||
#include <volk.h>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnullability-completeness"
|
||||
#endif
|
||||
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace plume {
|
||||
struct VulkanCommandQueue;
|
||||
struct VulkanDevice;
|
||||
struct VulkanInterface;
|
||||
struct VulkanPool;
|
||||
struct VulkanQueue;
|
||||
|
||||
struct VulkanBuffer : RenderBuffer {
|
||||
VkBuffer vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
VulkanPool *pool = nullptr;
|
||||
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||
VmaAllocationInfo allocationInfo = {};
|
||||
RenderBufferDesc desc;
|
||||
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
|
||||
|
||||
VulkanBuffer() = default;
|
||||
VulkanBuffer(VulkanDevice *device, VulkanPool *pool, const RenderBufferDesc &desc);
|
||||
~VulkanBuffer() override;
|
||||
void *map(uint32_t subresource, const RenderRange *readRange) override;
|
||||
void unmap(uint32_t subresource, const RenderRange *writtenRange) override;
|
||||
std::unique_ptr<RenderBufferFormattedView> createBufferFormattedView(RenderFormat format) override;
|
||||
void setName(const std::string &name) override;
|
||||
uint64_t getDeviceAddress() const override;
|
||||
};
|
||||
|
||||
struct VulkanBufferFormattedView : RenderBufferFormattedView {
|
||||
VkBufferView vk = VK_NULL_HANDLE;
|
||||
VulkanBuffer *buffer = nullptr;
|
||||
|
||||
VulkanBufferFormattedView(VulkanBuffer *buffer, RenderFormat format);
|
||||
~VulkanBufferFormattedView() override;
|
||||
};
|
||||
|
||||
struct VulkanTexture : RenderTexture {
|
||||
VkImage vk = VK_NULL_HANDLE;
|
||||
VkImageView imageView = VK_NULL_HANDLE;
|
||||
VkFormat imageFormat = VK_FORMAT_UNDEFINED;
|
||||
VkImageSubresourceRange imageSubresourceRange = {};
|
||||
VulkanDevice *device = nullptr;
|
||||
VulkanPool *pool = nullptr;
|
||||
VmaAllocation allocation = VK_NULL_HANDLE;
|
||||
VmaAllocationInfo allocationInfo = {};
|
||||
RenderTextureLayout textureLayout = RenderTextureLayout::UNKNOWN;
|
||||
RenderBarrierStages barrierStages = RenderBarrierStage::NONE;
|
||||
bool ownership = false;
|
||||
RenderTextureDesc desc;
|
||||
|
||||
VulkanTexture() = default;
|
||||
VulkanTexture(VulkanDevice *device, VulkanPool *pool, const RenderTextureDesc &desc);
|
||||
VulkanTexture(VulkanDevice *device, VkImage image);
|
||||
~VulkanTexture() override;
|
||||
void createImageView(VkFormat format);
|
||||
std::unique_ptr<RenderTextureView> createTextureView(const RenderTextureViewDesc &desc) override;
|
||||
void setName(const std::string &name) override;
|
||||
void fillSubresourceRange();
|
||||
};
|
||||
|
||||
struct VulkanTextureView : RenderTextureView {
|
||||
VkImageView vk = VK_NULL_HANDLE;
|
||||
VulkanTexture *texture = nullptr;
|
||||
|
||||
VulkanTextureView(VulkanTexture *texture, const RenderTextureViewDesc &desc);
|
||||
~VulkanTextureView() override;
|
||||
};
|
||||
|
||||
struct VulkanAccelerationStructure : RenderAccelerationStructure {
|
||||
VkAccelerationStructureKHR vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
RenderAccelerationStructureType type = RenderAccelerationStructureType::UNKNOWN;
|
||||
|
||||
VulkanAccelerationStructure(VulkanDevice *device, const RenderAccelerationStructureDesc &desc);
|
||||
~VulkanAccelerationStructure() override;
|
||||
};
|
||||
|
||||
struct VulkanDescriptorSetLayout {
|
||||
VkDescriptorSetLayout vk = VK_NULL_HANDLE;
|
||||
std::vector<VkDescriptorSetLayoutBinding> setBindings;
|
||||
std::vector<uint32_t> descriptorIndexBases;
|
||||
std::vector<uint32_t> descriptorBindingIndices;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanDescriptorSetLayout(VulkanDevice *device, const RenderDescriptorSetDesc &descriptorSetDesc);
|
||||
~VulkanDescriptorSetLayout();
|
||||
};
|
||||
|
||||
struct VulkanPipelineLayout : RenderPipelineLayout {
|
||||
VkPipelineLayout vk = VK_NULL_HANDLE;
|
||||
std::vector<VkPushConstantRange> pushConstantRanges;
|
||||
std::vector<VulkanDescriptorSetLayout *> descriptorSetLayouts;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanPipelineLayout(VulkanDevice *device, const RenderPipelineLayoutDesc &desc);
|
||||
~VulkanPipelineLayout() override;
|
||||
};
|
||||
|
||||
struct VulkanShader : RenderShader {
|
||||
VkShaderModule vk = VK_NULL_HANDLE;
|
||||
std::string entryPointName;
|
||||
VulkanDevice *device = nullptr;
|
||||
RenderShaderFormat format = RenderShaderFormat::UNKNOWN;
|
||||
|
||||
VulkanShader(VulkanDevice *device, const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format);
|
||||
~VulkanShader() override;
|
||||
};
|
||||
|
||||
struct VulkanSampler : RenderSampler {
|
||||
VkSampler vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanSampler(VulkanDevice *device, const RenderSamplerDesc &desc);
|
||||
~VulkanSampler();
|
||||
};
|
||||
|
||||
struct VulkanPipeline : RenderPipeline {
|
||||
enum class Type {
|
||||
Unknown,
|
||||
Compute,
|
||||
Graphics,
|
||||
Raytracing
|
||||
};
|
||||
|
||||
VulkanDevice *device = nullptr;
|
||||
Type type = Type::Unknown;
|
||||
|
||||
VulkanPipeline(VulkanDevice *device, Type type);
|
||||
virtual ~VulkanPipeline() override;
|
||||
};
|
||||
|
||||
struct VulkanComputePipeline : VulkanPipeline {
|
||||
VkPipeline vk = VK_NULL_HANDLE;
|
||||
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
||||
|
||||
VulkanComputePipeline(VulkanDevice *device, const RenderComputePipelineDesc &desc);
|
||||
~VulkanComputePipeline() override;
|
||||
void setName(const std::string& name) const override;
|
||||
RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct VulkanGraphicsPipeline : VulkanPipeline {
|
||||
VkPipeline vk = VK_NULL_HANDLE;
|
||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||
|
||||
VulkanGraphicsPipeline(VulkanDevice *device, const RenderGraphicsPipelineDesc &desc);
|
||||
~VulkanGraphicsPipeline() override;
|
||||
void setName(const std::string& name) const override;
|
||||
RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
static VkRenderPass createRenderPass(VulkanDevice *device, const VkFormat *renderTargetFormat, uint32_t renderTargetCount, VkFormat depthTargetFormat, VkSampleCountFlagBits sampleCount);
|
||||
};
|
||||
|
||||
struct VulkanRaytracingPipeline : VulkanPipeline {
|
||||
VkPipeline vk = VK_NULL_HANDLE;
|
||||
std::unordered_map<std::string, RenderPipelineProgram> nameProgramMap;
|
||||
uint32_t groupCount = 0;
|
||||
uint32_t descriptorSetCount = 0;
|
||||
|
||||
VulkanRaytracingPipeline(VulkanDevice *device, const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline);
|
||||
~VulkanRaytracingPipeline() override;
|
||||
void setName(const std::string& name) const override;
|
||||
RenderPipelineProgram getProgram(const std::string &name) const override;
|
||||
};
|
||||
|
||||
struct VulkanDescriptorSet : RenderDescriptorSet {
|
||||
VkDescriptorSet vk = VK_NULL_HANDLE;
|
||||
VulkanDescriptorSetLayout *setLayout = nullptr;
|
||||
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanDescriptorSet(VulkanDevice *device, const RenderDescriptorSetDesc &desc);
|
||||
~VulkanDescriptorSet() override;
|
||||
void setBuffer(uint32_t descriptorIndex, const RenderBuffer *buffer, uint64_t bufferSize, const RenderBufferStructuredView *bufferStructuredView, const RenderBufferFormattedView *bufferFormattedView) override;
|
||||
void setTexture(uint32_t descriptorIndex, const RenderTexture *texture, RenderTextureLayout textureLayout, const RenderTextureView *textureView) override;
|
||||
void setSampler(uint32_t descriptorIndex, const RenderSampler *sampler) override;
|
||||
void setAccelerationStructure(uint32_t descriptorIndex, const RenderAccelerationStructure *accelerationStructure) override;
|
||||
void setDescriptor(uint32_t descriptorIndex, const VkDescriptorBufferInfo *bufferInfo, const VkDescriptorImageInfo *imageInfo, const VkBufferView *texelBufferView, void *pNext);
|
||||
static VkDescriptorPool createDescriptorPool(VulkanDevice *device, const std::unordered_map<VkDescriptorType, uint32_t> &typeCounts, bool lastRangeIsBoundless);
|
||||
};
|
||||
|
||||
struct VulkanSwapChain : RenderSwapChain {
|
||||
VkSwapchainKHR vk = VK_NULL_HANDLE;
|
||||
VulkanCommandQueue *commandQueue = nullptr;
|
||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
RenderWindow renderWindow = {};
|
||||
uint32_t textureCount = 0;
|
||||
uint64_t presentCount = 0;
|
||||
RenderFormat format = RenderFormat::UNKNOWN;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
VkSwapchainCreateInfoKHR createInfo = {};
|
||||
VkSurfaceFormatKHR pickedSurfaceFormat = {};
|
||||
VkPresentModeKHR createdPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
VkPresentModeKHR requiredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
VkCompositeAlphaFlagBitsKHR pickedAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
std::vector<VulkanTexture> textures;
|
||||
uint64_t currentPresentId = 0;
|
||||
bool immediatePresentModeSupported = false;
|
||||
uint32_t maxFrameLatency = 0;
|
||||
|
||||
VulkanSwapChain(VulkanCommandQueue *commandQueue, RenderWindow renderWindow, uint32_t textureCount, RenderFormat format, uint32_t maxFrameLatency);
|
||||
~VulkanSwapChain() override;
|
||||
bool present(uint32_t textureIndex, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount) override;
|
||||
void wait() override;
|
||||
bool resize() override;
|
||||
bool needsResize() const override;
|
||||
void setVsyncEnabled(bool vsyncEnabled) override;
|
||||
bool isVsyncEnabled() const override;
|
||||
uint32_t getWidth() const override;
|
||||
uint32_t getHeight() const override;
|
||||
RenderTexture *getTexture(uint32_t textureIndex) override;
|
||||
uint32_t getTextureCount() const override;
|
||||
bool acquireTexture(RenderCommandSemaphore *signalSemaphore, uint32_t *textureIndex) override;
|
||||
RenderWindow getWindow() const override;
|
||||
bool isEmpty() const override;
|
||||
uint32_t getRefreshRate() const override;
|
||||
void getWindowSize(uint32_t &dstWidth, uint32_t &dstHeight) const;
|
||||
void releaseSwapChain();
|
||||
void releaseImageViews();
|
||||
};
|
||||
|
||||
struct VulkanFramebuffer : RenderFramebuffer {
|
||||
VulkanDevice *device = nullptr;
|
||||
VkFramebuffer vk = VK_NULL_HANDLE;
|
||||
VkRenderPass renderPass = VK_NULL_HANDLE;
|
||||
std::vector<const VulkanTexture *> colorAttachments;
|
||||
const VulkanTexture *depthAttachment = nullptr;
|
||||
bool depthAttachmentReadOnly = false;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
|
||||
VulkanFramebuffer(VulkanDevice *device, const RenderFramebufferDesc &desc);
|
||||
~VulkanFramebuffer() override;
|
||||
uint32_t getWidth() const override;
|
||||
uint32_t getHeight() const override;
|
||||
bool contains(const VulkanTexture *attachment) const;
|
||||
};
|
||||
|
||||
struct VulkanQueryPool : RenderQueryPool {
|
||||
VulkanDevice *device = nullptr;
|
||||
std::vector<uint64_t> results;
|
||||
VkQueryPool vk = VK_NULL_HANDLE;
|
||||
|
||||
VulkanQueryPool(VulkanDevice *device, uint32_t queryCount);
|
||||
virtual ~VulkanQueryPool() override;
|
||||
virtual void queryResults() override;
|
||||
virtual const uint64_t *getResults() const override;
|
||||
virtual uint32_t getCount() const override;
|
||||
};
|
||||
|
||||
struct VulkanCommandList : RenderCommandList {
|
||||
VkCommandBuffer vk = VK_NULL_HANDLE;
|
||||
VkCommandPool commandPool = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
RenderCommandListType type = RenderCommandListType::UNKNOWN;
|
||||
const VulkanFramebuffer *targetFramebuffer = nullptr;
|
||||
const VulkanPipelineLayout *activeComputePipelineLayout = nullptr;
|
||||
const VulkanPipelineLayout *activeGraphicsPipelineLayout = nullptr;
|
||||
const VulkanPipelineLayout *activeRaytracingPipelineLayout = nullptr;
|
||||
VkRenderPass activeRenderPass = VK_NULL_HANDLE;
|
||||
|
||||
VulkanCommandList(VulkanDevice *device, RenderCommandListType type);
|
||||
~VulkanCommandList() override;
|
||||
void begin() override;
|
||||
void end() override;
|
||||
void barriers(RenderBarrierStages stages, const RenderBufferBarrier *bufferBarriers, uint32_t bufferBarriersCount, const RenderTextureBarrier *textureBarriers, uint32_t textureBarriersCount) override;
|
||||
void dispatch(uint32_t threadGroupCountX, uint32_t threadGroupCountY, uint32_t threadGroupCountZ) override;
|
||||
void traceRays(uint32_t width, uint32_t height, uint32_t depth, RenderBufferReference shaderBindingTable, const RenderShaderBindingGroupsInfo &shaderBindingGroupsInfo) override;
|
||||
void drawInstanced(uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation) override;
|
||||
void drawIndexedInstanced(uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation) override;
|
||||
void setPipeline(const RenderPipeline *pipeline) override;
|
||||
void setComputePipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setComputePushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setComputeDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setGraphicsPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setGraphicsPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setGraphicsDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setGraphicsRootDescriptor(RenderBufferReference bufferReference, uint32_t rootDescriptorIndex) override;
|
||||
void setRaytracingPipelineLayout(const RenderPipelineLayout *pipelineLayout) override;
|
||||
void setRaytracingPushConstants(uint32_t rangeIndex, const void *data, uint32_t offset = 0, uint32_t size = 0) override;
|
||||
void setRaytracingDescriptorSet(RenderDescriptorSet *descriptorSet, uint32_t setIndex) override;
|
||||
void setIndexBuffer(const RenderIndexBufferView *view) override;
|
||||
void setVertexBuffers(uint32_t startSlot, const RenderVertexBufferView *views, uint32_t viewCount, const RenderInputSlot *inputSlots) override;
|
||||
void setViewports(const RenderViewport *viewports, uint32_t count) override;
|
||||
void setScissors(const RenderRect *scissorRects, uint32_t count) override;
|
||||
void setFramebuffer(const RenderFramebuffer *framebuffer) override;
|
||||
void setDepthBias(float depthBias, float depthBiasClamp, float slopeScaledDepthBias) override;
|
||||
void clearColor(uint32_t attachmentIndex, RenderColor colorValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
|
||||
void clearDepth(bool clearDepth, float depthValue, const RenderRect *clearRects, uint32_t clearRectsCount) override;
|
||||
void copyBufferRegion(RenderBufferReference dstBuffer, RenderBufferReference srcBuffer, uint64_t size) override;
|
||||
void copyTextureRegion(const RenderTextureCopyLocation &dstLocation, const RenderTextureCopyLocation &srcLocation, uint32_t dstX, uint32_t dstY, uint32_t dstZ, const RenderBox *srcBox) override;
|
||||
void copyBuffer(const RenderBuffer *dstBuffer, const RenderBuffer *srcBuffer) override;
|
||||
void copyTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||
void resolveTexture(const RenderTexture *dstTexture, const RenderTexture *srcTexture) override;
|
||||
void resolveTextureRegion(const RenderTexture *dstTexture, uint32_t dstX, uint32_t dstY, const RenderTexture *srcTexture, const RenderRect *srcRect, RenderResolveMode resolveMode) override;
|
||||
void buildBottomLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, const RenderBottomLevelASBuildInfo &buildInfo) override;
|
||||
void buildTopLevelAS(const RenderAccelerationStructure *dstAccelerationStructure, RenderBufferReference scratchBuffer, RenderBufferReference instancesBuffer, const RenderTopLevelASBuildInfo &buildInfo) override;
|
||||
void discardTexture(const RenderTexture* texture) override;
|
||||
void resetQueryPool(const RenderQueryPool *queryPool, uint32_t queryFirstIndex, uint32_t queryCount) override;
|
||||
void writeTimestamp(const RenderQueryPool *queryPool, uint32_t queryIndex) override;
|
||||
void checkActiveRenderPass();
|
||||
void endActiveRenderPass();
|
||||
void setDescriptorSet(VkPipelineBindPoint bindPoint, const VulkanPipelineLayout *pipelineLayout, const RenderDescriptorSet *descriptorSet, uint32_t setIndex);
|
||||
};
|
||||
|
||||
struct VulkanCommandFence : RenderCommandFence {
|
||||
VkFence vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanCommandFence(VulkanDevice *device);
|
||||
~VulkanCommandFence() override;
|
||||
};
|
||||
|
||||
struct VulkanCommandSemaphore : RenderCommandSemaphore {
|
||||
VkSemaphore vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanCommandSemaphore(VulkanDevice *device);
|
||||
~VulkanCommandSemaphore() override;
|
||||
};
|
||||
|
||||
struct VulkanCommandQueue : RenderCommandQueue {
|
||||
VulkanQueue *queue = nullptr;
|
||||
VulkanDevice *device = nullptr;
|
||||
uint32_t familyIndex = 0;
|
||||
uint32_t queueIndex = 0;
|
||||
std::unordered_set<VulkanSwapChain *> swapChains;
|
||||
|
||||
VulkanCommandQueue(VulkanDevice *device, RenderCommandListType commandListType);
|
||||
~VulkanCommandQueue() override;
|
||||
std::unique_ptr<RenderSwapChain> createSwapChain(RenderWindow renderWindow, uint32_t bufferCount, RenderFormat format, uint32_t maxFrameLatency) override;
|
||||
void executeCommandLists(const RenderCommandList **commandLists, uint32_t commandListCount, RenderCommandSemaphore **waitSemaphores, uint32_t waitSemaphoreCount, RenderCommandSemaphore **signalSemaphores, uint32_t signalSemaphoreCount, RenderCommandFence *signalFence) override;
|
||||
void waitForCommandFence(RenderCommandFence *fence) override;
|
||||
};
|
||||
|
||||
struct VulkanPool : RenderPool {
|
||||
VmaPool vk = VK_NULL_HANDLE;
|
||||
VulkanDevice *device = nullptr;
|
||||
|
||||
VulkanPool(VulkanDevice *device, const RenderPoolDesc &desc);
|
||||
~VulkanPool() override;
|
||||
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
|
||||
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
|
||||
};
|
||||
|
||||
struct VulkanQueue {
|
||||
VkQueue vk;
|
||||
std::unique_ptr<std::mutex> mutex;
|
||||
std::unordered_set<const VulkanCommandQueue *> virtualQueues;
|
||||
};
|
||||
|
||||
struct VulkanQueueFamily {
|
||||
std::vector<VulkanQueue> queues;
|
||||
|
||||
void add(VulkanCommandQueue *virtualQueue);
|
||||
void remove(VulkanCommandQueue *virtualQueue);
|
||||
};
|
||||
|
||||
struct VulkanDevice : RenderDevice {
|
||||
VkDevice vk = VK_NULL_HANDLE;
|
||||
VulkanInterface *renderInterface = nullptr;
|
||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
||||
VkPhysicalDeviceProperties physicalDeviceProperties = {};
|
||||
VmaAllocator allocator = VK_NULL_HANDLE;
|
||||
uint32_t queueFamilyIndices[3] = {};
|
||||
std::vector<VulkanQueueFamily> queueFamilies;
|
||||
RenderDeviceCapabilities capabilities;
|
||||
RenderDeviceDescription description;
|
||||
VkPhysicalDeviceRayTracingPipelinePropertiesKHR rtPipelineProperties = {};
|
||||
VkPhysicalDeviceSampleLocationsPropertiesEXT sampleLocationProperties = {};
|
||||
bool loadStoreOpNoneSupported = false;
|
||||
|
||||
VulkanDevice(VulkanInterface *renderInterface, const std::string &preferredDeviceName);
|
||||
~VulkanDevice() override;
|
||||
std::unique_ptr<RenderCommandList> createCommandList(RenderCommandListType type) override;
|
||||
std::unique_ptr<RenderDescriptorSet> createDescriptorSet(const RenderDescriptorSetDesc &desc) override;
|
||||
std::unique_ptr<RenderShader> createShader(const void *data, uint64_t size, const char *entryPointName, RenderShaderFormat format) override;
|
||||
std::unique_ptr<RenderSampler> createSampler(const RenderSamplerDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createComputePipeline(const RenderComputePipelineDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createGraphicsPipeline(const RenderGraphicsPipelineDesc &desc) override;
|
||||
std::unique_ptr<RenderPipeline> createRaytracingPipeline(const RenderRaytracingPipelineDesc &desc, const RenderPipeline *previousPipeline) override;
|
||||
std::unique_ptr<RenderCommandQueue> createCommandQueue(RenderCommandListType type) override;
|
||||
std::unique_ptr<RenderBuffer> createBuffer(const RenderBufferDesc &desc) override;
|
||||
std::unique_ptr<RenderTexture> createTexture(const RenderTextureDesc &desc) override;
|
||||
std::unique_ptr<RenderAccelerationStructure> createAccelerationStructure(const RenderAccelerationStructureDesc &desc) override;
|
||||
std::unique_ptr<RenderPool> createPool(const RenderPoolDesc &desc) override;
|
||||
std::unique_ptr<RenderPipelineLayout> createPipelineLayout(const RenderPipelineLayoutDesc &desc) override;
|
||||
std::unique_ptr<RenderCommandFence> createCommandFence() override;
|
||||
std::unique_ptr<RenderCommandSemaphore> createCommandSemaphore() override;
|
||||
std::unique_ptr<RenderFramebuffer> createFramebuffer(const RenderFramebufferDesc &desc) override;
|
||||
std::unique_ptr<RenderQueryPool> createQueryPool(uint32_t queryCount) override;
|
||||
void setBottomLevelASBuildInfo(RenderBottomLevelASBuildInfo &buildInfo, const RenderBottomLevelASMesh *meshes, uint32_t meshCount, bool preferFastBuild, bool preferFastTrace) override;
|
||||
void setTopLevelASBuildInfo(RenderTopLevelASBuildInfo &buildInfo, const RenderTopLevelASInstance *instances, uint32_t instanceCount, bool preferFastBuild, bool preferFastTrace) override;
|
||||
void setShaderBindingTableInfo(RenderShaderBindingTableInfo &tableInfo, const RenderShaderBindingGroups &groups, const RenderPipeline *pipeline, RenderDescriptorSet **descriptorSets, uint32_t descriptorSetCount) override;
|
||||
const RenderDeviceCapabilities &getCapabilities() const override;
|
||||
const RenderDeviceDescription &getDescription() const override;
|
||||
RenderSampleCounts getSampleCountsSupported(RenderFormat format) const override;
|
||||
void waitIdle() const override;
|
||||
void release();
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
struct VulkanInterface : RenderInterface {
|
||||
VkInstance instance = VK_NULL_HANDLE;
|
||||
VkApplicationInfo appInfo = {};
|
||||
RenderInterfaceCapabilities capabilities;
|
||||
std::vector<std::string> deviceNames;
|
||||
|
||||
# if SDL_VULKAN_ENABLED
|
||||
VulkanInterface(RenderWindow sdlWindow);
|
||||
# else
|
||||
VulkanInterface();
|
||||
# endif
|
||||
|
||||
~VulkanInterface() override;
|
||||
std::unique_ptr<RenderDevice> createDevice(const std::string &preferredDeviceName) override;
|
||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||
const std::vector<std::string> &getDeviceNames() const override;
|
||||
bool isValid() const;
|
||||
};
|
||||
};
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include <magic_enum/magic_enum.hpp>
|
||||
#endif
|
||||
|
||||
#define UNLEASHED_RECOMP
|
||||
#include "../../tools/XenosRecomp/XenosRecomp/shader_common.h"
|
||||
|
||||
#ifdef UNLEASHED_RECOMP_D3D12
|
||||
|
|
@ -1837,7 +1838,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
|||
g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);
|
||||
|
||||
for (auto& commandList : g_commandLists)
|
||||
commandList = g_device->createCommandList(RenderCommandListType::DIRECT);
|
||||
commandList = g_queue->createCommandList();
|
||||
|
||||
for (auto& commandFence : g_commandFences)
|
||||
commandFence = g_device->createCommandFence();
|
||||
|
|
@ -1846,7 +1847,7 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
|
|||
queryPool = g_device->createQueryPool(NUM_QUERIES);
|
||||
|
||||
g_copyQueue = g_device->createCommandQueue(RenderCommandListType::COPY);
|
||||
g_copyCommandList = g_device->createCommandList(RenderCommandListType::COPY);
|
||||
g_copyCommandList = g_copyQueue->createCommandList();
|
||||
g_copyCommandFence = g_device->createCommandFence();
|
||||
|
||||
uint32_t bufferCount = 2;
|
||||
|
|
@ -2074,12 +2075,7 @@ void Video::WaitForGPU()
|
|||
{
|
||||
g_waitForGPUCount++;
|
||||
|
||||
if (g_vulkan)
|
||||
{
|
||||
g_device->waitIdle();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wait for all queued frames to finish.
|
||||
for (size_t i = 0; i < NUM_FRAMES; i++)
|
||||
{
|
||||
if (g_commandListStates[i])
|
||||
|
|
@ -2088,9 +2084,12 @@ void Video::WaitForGPU()
|
|||
g_commandListStates[i] = false;
|
||||
}
|
||||
}
|
||||
g_queue->executeCommandLists(nullptr, g_commandFences[0].get());
|
||||
|
||||
// Execute an empty command list and wait for it to end to guarantee that any remaining presentation has finished.
|
||||
g_commandLists[0]->begin();
|
||||
g_commandLists[0]->end();
|
||||
g_queue->executeCommandLists(g_commandLists[0].get(), g_commandFences[0].get());
|
||||
g_queue->waitForCommandFence(g_commandFences[0].get());
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t CreateDevice(uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5, be<uint32_t>* a6)
|
||||
|
|
@ -5736,7 +5735,7 @@ static bool LoadTexture(GuestTexture& texture, const uint8_t* data, size_t dataS
|
|||
auto copyTextureRegion = [&](Slice& slice, uint32_t subresourceIndex)
|
||||
{
|
||||
g_copyCommandList->copyTextureRegion(
|
||||
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex),
|
||||
RenderTextureCopyLocation::Subresource(texture.texture, subresourceIndex % ddsDesc.numMips, subresourceIndex / ddsDesc.numMips),
|
||||
RenderTextureCopyLocation::PlacedFootprint(uploadBuffer.get(), desc.format, slice.width, slice.height, slice.depth, (slice.dstRowPitch * 8) / ddsDesc.bitsPerPixelOrBlock * ddsDesc.blockWidth, slice.dstOffset));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
/////////////////////////////////////////////////////////////////////#define PSO_CACHING
|
||||
//#define PSO_CACHING_CLEANUP
|
||||
|
||||
#include "rhi/plume_render_interface.h"
|
||||
#include <plume_render_interface.h>
|
||||
|
||||
#define D3DCLEAR_TARGET 0x1
|
||||
#define D3DCLEAR_ZBUFFER 0x10
|
||||
|
|
|
|||
|
|
@ -166,6 +166,9 @@ void UpdateChecker::visitWebsite()
|
|||
#elif defined(__linux__)
|
||||
std::string command = "xdg-open " + std::string(VISIT_URL) + " &";
|
||||
std::system(command.c_str());
|
||||
#elif defined(__APPLE__)
|
||||
std::string command = "open " + std::string(VISIT_URL) + " &";
|
||||
std::system(command.c_str());
|
||||
#else
|
||||
static_assert(false, "Visit website not implemented for this platform.");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ void KeQueryBasePriorityThread()
|
|||
|
||||
uint32_t NtSuspendThread(GuestThreadHandle* hThread, uint32_t* suspendCount)
|
||||
{
|
||||
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->thread.get_id() == std::this_thread::get_id());
|
||||
assert(hThread != GetKernelObject(CURRENT_THREAD_HANDLE) && hThread->GetThreadId() == GuestThread::GetCurrentThreadId());
|
||||
|
||||
hThread->suspended = true;
|
||||
hThread->suspended.wait(true);
|
||||
|
|
|
|||
|
|
@ -306,26 +306,26 @@ uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName, const
|
|||
|
||||
if (!exists)
|
||||
{
|
||||
std::string root = "";
|
||||
std::filesystem::path rootPath;
|
||||
|
||||
if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
|
||||
{
|
||||
std::u8string savePathU8 = GetSavePath(true).u8string();
|
||||
root = (const char *)(savePathU8.c_str());
|
||||
rootPath = GetSavePath(true);
|
||||
}
|
||||
else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
|
||||
{
|
||||
root = GAME_INSTALL_DIRECTORY "/dlc";
|
||||
rootPath = GetGamePath() / "dlc";
|
||||
}
|
||||
else
|
||||
{
|
||||
root = GAME_INSTALL_DIRECTORY;
|
||||
rootPath = GetGamePath();
|
||||
}
|
||||
|
||||
const std::string root = (const char*)rootPath.u8string().c_str();
|
||||
XamRegisterContent(*pContentData, root);
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directory(std::u8string_view((const char8_t*)(root.c_str())), ec);
|
||||
std::filesystem::create_directory(rootPath, ec);
|
||||
|
||||
XamRootCreate(szRootName, root);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include <stdafx.h>
|
||||
#ifdef __x86_64__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#include <cpu/guest_thread.h>
|
||||
#include <gpu/video.h>
|
||||
#include <kernel/function.h>
|
||||
|
|
@ -69,8 +71,10 @@ void KiSystemStartup()
|
|||
|
||||
const auto gameContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Game");
|
||||
const auto updateContent = XamMakeContent(XCONTENTTYPE_RESERVED, "Update");
|
||||
XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
|
||||
XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update");
|
||||
const std::string gamePath = (const char*)(GetGamePath() / "game").u8string().c_str();
|
||||
const std::string updatePath = (const char*)(GetGamePath() / "update").u8string().c_str();
|
||||
XamRegisterContent(gameContent, gamePath);
|
||||
XamRegisterContent(updateContent, updatePath);
|
||||
|
||||
const auto saveFilePath = GetSaveFilePath(true);
|
||||
bool saveFileExists = std::filesystem::exists(saveFilePath);
|
||||
|
|
@ -102,7 +106,7 @@ void KiSystemStartup()
|
|||
XamContentCreateEx(0, "D", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
|
||||
|
||||
std::error_code ec;
|
||||
for (auto& file : std::filesystem::directory_iterator(GAME_INSTALL_DIRECTORY "/dlc", ec))
|
||||
for (auto& file : std::filesystem::directory_iterator(GetGamePath() / "dlc", ec))
|
||||
{
|
||||
if (file.is_directory())
|
||||
{
|
||||
|
|
@ -165,10 +169,10 @@ uint32_t LdrLoadModule(const std::filesystem::path &path)
|
|||
return entry;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
__attribute__((constructor(101), target("no-avx,no-avx2"), noinline))
|
||||
void init()
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
// Execute CPUID for processor info and feature bits.
|
||||
|
|
@ -185,8 +189,8 @@ void init()
|
|||
|
||||
std::_Exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -232,7 +236,7 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
// Set the current working directory to the executable's path.
|
||||
std::error_code ec;
|
||||
std::filesystem::current_path(os::process::GetExecutablePath().parent_path(), ec);
|
||||
std::filesystem::current_path(os::process::GetExecutableRoot(), ec);
|
||||
}
|
||||
|
||||
Config::Load();
|
||||
|
|
@ -321,7 +325,7 @@ int main(int argc, char *argv[])
|
|||
HostStartup();
|
||||
|
||||
std::filesystem::path modulePath;
|
||||
bool isGameInstalled = Installer::checkGameInstall(GAME_INSTALL_DIRECTORY, modulePath);
|
||||
bool isGameInstalled = Installer::checkGameInstall(GetGamePath(), modulePath);
|
||||
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
|
||||
if (runInstallerWizard)
|
||||
{
|
||||
|
|
@ -331,7 +335,7 @@ int main(int argc, char *argv[])
|
|||
std::_Exit(1);
|
||||
}
|
||||
|
||||
if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
|
||||
if (!InstallerWizard::Run(GetGamePath(), isGameInstalled && forceDLCInstaller))
|
||||
{
|
||||
std::_Exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ void ModLoader::Init()
|
|||
{
|
||||
configIni = {};
|
||||
|
||||
if (!configIni.read(GAME_INSTALL_DIRECTORY "/cpkredir.ini"))
|
||||
if (!configIni.read(GetGamePath() / "cpkredir.ini"))
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,11 @@ std::filesystem::path os::process::GetExecutablePath()
|
|||
}
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetExecutableRoot()
|
||||
{
|
||||
return GetExecutablePath().remove_filename();
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetWorkingDirectory()
|
||||
{
|
||||
char cwd[PATH_MAX] = {};
|
||||
|
|
|
|||
17
UnleashedRecomp/os/macos/logger_macos.cpp
Normal file
17
UnleashedRecomp/os/macos/logger_macos.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include <os/logger.h>
|
||||
|
||||
void os::logger::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void os::logger::Log(const std::string_view str, ELogType type, const char* func)
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
fmt::println("[{}] {}", func, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::println("{}", str);
|
||||
}
|
||||
}
|
||||
7
UnleashedRecomp/os/macos/media_macos.cpp
Normal file
7
UnleashedRecomp/os/macos/media_macos.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include <os/media.h>
|
||||
|
||||
bool os::media::IsExternalMediaPlaying()
|
||||
{
|
||||
// This functionality is not supported in macOS.
|
||||
return false;
|
||||
}
|
||||
97
UnleashedRecomp/os/macos/process_macos.cpp
Normal file
97
UnleashedRecomp/os/macos/process_macos.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
#include <os/process.h>
|
||||
|
||||
#include <CoreFoundation/CFBundle.h>
|
||||
#include <dlfcn.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
|
||||
std::filesystem::path os::process::GetExecutablePath()
|
||||
{
|
||||
uint32_t exePathSize = PATH_MAX;
|
||||
char exePath[PATH_MAX] = {};
|
||||
if (_NSGetExecutablePath(exePath, &exePathSize) == 0)
|
||||
{
|
||||
return std::filesystem::path(std::u8string_view((const char8_t*)(exePath)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::filesystem::path();
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetExecutableRoot()
|
||||
{
|
||||
std::filesystem::path resultPath = GetExecutablePath().remove_filename();
|
||||
if (CFBundleRef bundleRef = CFBundleGetMainBundle())
|
||||
{
|
||||
if (CFURLRef bundleUrlRef = CFBundleCopyBundleURL(bundleRef))
|
||||
{
|
||||
char appBundlePath[MAXPATHLEN];
|
||||
if (CFURLGetFileSystemRepresentation(bundleUrlRef, true, (uint8_t*)(appBundlePath), sizeof(appBundlePath)))
|
||||
{
|
||||
resultPath = std::filesystem::path(appBundlePath).parent_path();
|
||||
}
|
||||
CFRelease(bundleUrlRef);
|
||||
}
|
||||
}
|
||||
return resultPath;
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetWorkingDirectory()
|
||||
{
|
||||
char cwd[PATH_MAX] = {};
|
||||
char *res = getcwd(cwd, sizeof(cwd));
|
||||
if (res != nullptr)
|
||||
{
|
||||
return std::filesystem::path(std::u8string_view((const char8_t*)(cwd)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::filesystem::path();
|
||||
}
|
||||
}
|
||||
|
||||
bool os::process::SetWorkingDirectory(const std::filesystem::path& path)
|
||||
{
|
||||
return chdir(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
bool os::process::StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
return false;
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
setsid();
|
||||
|
||||
std::u8string workU8 = work.u8string();
|
||||
chdir((const char*)(workU8.c_str()));
|
||||
|
||||
std::u8string pathU8 = path.u8string();
|
||||
std::vector<char*> argStrs;
|
||||
argStrs.push_back((char*)(pathU8.c_str()));
|
||||
for (const std::string& arg : args)
|
||||
argStrs.push_back((char *)(arg.c_str()));
|
||||
|
||||
argStrs.push_back(nullptr);
|
||||
execvp((const char*)(pathU8.c_str()), argStrs.data());
|
||||
raise(SIGKILL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void os::process::CheckConsole()
|
||||
{
|
||||
// Always visible on macOS.
|
||||
g_consoleVisible = true;
|
||||
}
|
||||
|
||||
void os::process::ShowConsole()
|
||||
{
|
||||
// Unnecessary on macOS.
|
||||
}
|
||||
21
UnleashedRecomp/os/macos/registry_macos.inl
Normal file
21
UnleashedRecomp/os/macos/registry_macos.inl
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include <os/registry.h>
|
||||
|
||||
// TODO: Implement
|
||||
inline bool os::registry::Init()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: read from file?
|
||||
template<typename T>
|
||||
bool os::registry::ReadValue(const std::string_view& name, T& data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: write to file?
|
||||
template<typename T>
|
||||
bool os::registry::WriteValue(const std::string_view& name, const T& data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
6
UnleashedRecomp/os/macos/user_macos.cpp
Normal file
6
UnleashedRecomp/os/macos/user_macos.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include <os/user.h>
|
||||
|
||||
bool os::user::IsDarkTheme()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
7
UnleashedRecomp/os/macos/version_macos.cpp
Normal file
7
UnleashedRecomp/os/macos/version_macos.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
#include <os/version.h>
|
||||
|
||||
os::version::OSVersion os::version::GetOSVersion()
|
||||
{
|
||||
assert(false && "Unimplemented.");
|
||||
return os::version::OSVersion();
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ namespace os::process
|
|||
inline bool g_consoleVisible;
|
||||
|
||||
std::filesystem::path GetExecutablePath();
|
||||
std::filesystem::path GetExecutableRoot();
|
||||
std::filesystem::path GetWorkingDirectory();
|
||||
bool SetWorkingDirectory(const std::filesystem::path& path);
|
||||
bool StartProcess(const std::filesystem::path& path, const std::vector<std::string>& args, std::filesystem::path work = {});
|
||||
|
|
|
|||
|
|
@ -15,4 +15,6 @@ namespace os::registry
|
|||
#include <os/win32/registry_win32.inl>
|
||||
#elif defined(__linux__)
|
||||
#include <os/linux/registry_linux.inl>
|
||||
#elif defined(__APPLE__)
|
||||
#include <os/macos/registry_macos.inl>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ std::filesystem::path os::process::GetExecutablePath()
|
|||
return std::filesystem::path(exePath);
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetExecutableRoot()
|
||||
{
|
||||
return GetExecutablePath().remove_filename();
|
||||
}
|
||||
|
||||
std::filesystem::path os::process::GetWorkingDirectory()
|
||||
{
|
||||
WCHAR workPath[MAX_PATH];
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
42
UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
Normal file
42
UnleashedRecomp/res/macos/MacOSXBundleInfo.plist.in
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>13.0</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>GCSupportsGameMode</key>
|
||||
<true/>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
UnleashedRecomp/res/macos/game_icon.icns
Normal file
BIN
UnleashedRecomp/res/macos/game_icon.icns
Normal file
Binary file not shown.
|
|
@ -20,7 +20,7 @@ std::unique_ptr<GuestTexture> g_upKBMIcons;
|
|||
|
||||
float g_sideMargins = DEFAULT_SIDE_MARGINS;
|
||||
|
||||
std::vector<Button> g_buttons;
|
||||
static std::vector<Button> g_buttons;
|
||||
|
||||
std::unordered_map<EButtonIcon, float> g_iconWidths =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@ void GameWindow::Init(const char* sdlVideoDriver)
|
|||
s_renderWindow = s_pWindow;
|
||||
#elif defined(__linux__)
|
||||
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
||||
#elif defined(__APPLE__)
|
||||
s_renderWindow.window = info.info.cocoa.window;
|
||||
s_renderWindow.view = SDL_Metal_GetLayer(SDL_Metal_CreateView(s_pWindow));
|
||||
#else
|
||||
static_assert(false, "Unknown platform.");
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <gpu/rhi/plume_render_interface_types.h>
|
||||
#include <plume_render_interface_types.h>
|
||||
#include <user/config.h>
|
||||
#include <sdl_events.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -1146,7 +1146,11 @@ static void PickerStart(bool folderMode) {
|
|||
g_currentPickerVisible = true;
|
||||
|
||||
// Optional single thread mode for testing on systems that do not interact well with the separate thread being used for NFD.
|
||||
#ifdef __APPLE__
|
||||
constexpr bool singleThreadMode = true;
|
||||
#else
|
||||
constexpr bool singleThreadMode = false;
|
||||
#endif
|
||||
if (singleThreadMode)
|
||||
PickerThreadProcess();
|
||||
else
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ static ImFont* g_fntSeurat;
|
|||
|
||||
std::string g_text;
|
||||
int g_result;
|
||||
std::vector<std::string> g_buttons;
|
||||
static std::vector<std::string> g_buttons;
|
||||
int g_defaultButtonIndex;
|
||||
int g_cancelButtonIndex;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "paths.h"
|
||||
#include <os/process.h>
|
||||
|
||||
std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename();
|
||||
std::filesystem::path g_executableRoot = os::process::GetExecutableRoot();
|
||||
std::filesystem::path g_userPath = BuildUserPath();
|
||||
|
||||
bool CheckPortable()
|
||||
|
|
@ -22,18 +22,24 @@ std::filesystem::path BuildUserPath()
|
|||
userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY;
|
||||
|
||||
CoTaskMemFree(knownPath);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
const char* homeDir = getenv("HOME");
|
||||
#if defined(__linux__)
|
||||
if (homeDir == nullptr)
|
||||
{
|
||||
homeDir = getpwuid(getuid())->pw_dir;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (homeDir != nullptr)
|
||||
{
|
||||
// Prefer to store in the .config directory if it exists. Use the home directory otherwise.
|
||||
std::filesystem::path homePath = homeDir;
|
||||
#if defined(__linux__)
|
||||
std::filesystem::path configPath = homePath / ".config";
|
||||
#else
|
||||
std::filesystem::path configPath = homePath / "Library" / "Application Support";
|
||||
#endif
|
||||
if (std::filesystem::exists(configPath))
|
||||
userPath = configPath / USER_DIRECTORY;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -10,15 +10,22 @@
|
|||
|
||||
extern std::filesystem::path g_executableRoot;
|
||||
|
||||
inline std::filesystem::path GetGamePath()
|
||||
{
|
||||
return GAME_INSTALL_DIRECTORY;
|
||||
}
|
||||
|
||||
bool CheckPortable();
|
||||
std::filesystem::path BuildUserPath();
|
||||
const std::filesystem::path& GetUserPath();
|
||||
|
||||
inline std::filesystem::path GetGamePath()
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// On macOS, there is the expectation that the app may be installed to
|
||||
// /Applications/, and the bundle should not be modified. Thus we need
|
||||
// to install game files to the user directory instead of next to the app.
|
||||
return GetUserPath();
|
||||
#else
|
||||
return GAME_INSTALL_DIRECTORY;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::filesystem::path GetSavePath(bool checkForMods)
|
||||
{
|
||||
if (checkForMods && !ModLoader::s_saveFilePath.empty())
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ add_custom_command(
|
|||
"${CMAKE_CURRENT_SOURCE_DIR}/private/default.xex"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/private/default.xexp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/config/SWA.toml"
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
|
|
@ -53,6 +54,7 @@ target_compile_definitions(XenosRecomp PRIVATE
|
|||
XENOS_RECOMP_INPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/private\"
|
||||
XENOS_RECOMP_OUTPUT=\"${CMAKE_CURRENT_SOURCE_DIR}/shader/shader_cache.cpp\"
|
||||
XENOS_RECOMP_INCLUDE_INPUT=\"${XENOS_RECOMP_INCLUDE}\"
|
||||
UNLEASHED_RECOMP
|
||||
)
|
||||
|
||||
file(GLOB XENOS_RECOMP_SOURCES
|
||||
|
|
@ -70,6 +72,7 @@ add_custom_command(
|
|||
"${CMAKE_CURRENT_SOURCE_DIR}/private/shader_decompressed.ar"
|
||||
${XENOS_RECOMP_SOURCES}
|
||||
${XENOS_RECOMP_INCLUDE}
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
add_library(UnleashedRecompLib
|
||||
|
|
@ -79,4 +82,5 @@ add_library(UnleashedRecompLib
|
|||
)
|
||||
|
||||
target_include_directories(UnleashedRecompLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_include_directories(UnleashedRecompLib PRIVATE "${UNLEASHED_RECOMP_TOOLS_ROOT}/XenonRecomp/thirdparty/simde")
|
||||
target_precompile_headers(UnleashedRecompLib PUBLIC "ppc/ppc_recomp_shared.h")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
```
|
||||
|
|
|
|||
5
thirdparty/CMakeLists.txt
vendored
5
thirdparty/CMakeLists.txt
vendored
|
|
@ -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
thirdparty/D3D12MemoryAllocator
vendored
1
thirdparty/D3D12MemoryAllocator
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit e00c4a7c85cf9c28c6f4a6cc75032736f416410f
|
||||
86
thirdparty/MoltenVK/CMakeLists.txt
vendored
Normal file
86
thirdparty/MoltenVK/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# Simple CMake script to compile MoltenVK with SPIRV-Cross as a shared library target
|
||||
|
||||
# Prepare MoltenVK Git revision
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
OUTPUT_VARIABLE MVK_GIT_REV
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
set(MVK_GENERATED_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/Generated)
|
||||
file(WRITE ${MVK_GENERATED_INCLUDES}/mvkGitRevDerived.h "static const char* mvkRevString = \"${MVK_GIT_REV}\";")
|
||||
message(STATUS "MoltenVK revision: ${MVK_GIT_REV}")
|
||||
|
||||
# Prepare MoltenVK version
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/MoltenVK/API/mvk_private_api.h MVK_PRIVATE_API)
|
||||
string(REGEX MATCH "#define MVK_VERSION_MAJOR [0-9]+" MVK_VERSION_MAJOR_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_MAJOR "${MVK_VERSION_MAJOR_LINE}")
|
||||
string(REGEX MATCH "#define MVK_VERSION_MINOR [0-9]+" MVK_VERSION_MINOR_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_MINOR "${MVK_VERSION_MINOR_LINE}")
|
||||
string(REGEX MATCH "#define MVK_VERSION_PATCH [0-9]+" MVK_VERSION_PATCH_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_PATCH "${MVK_VERSION_PATCH_LINE}")
|
||||
set(MVK_VERSION "${MVK_VERSION_MAJOR}.${MVK_VERSION_MINOR}.${MVK_VERSION_PATCH}")
|
||||
message(STATUS "MoltenVK version: ${MVK_VERSION}")
|
||||
|
||||
# Find required system libraries
|
||||
find_library(APPKIT_LIBRARY AppKit REQUIRED)
|
||||
find_library(FOUNDATION_LIBRARY Foundation REQUIRED)
|
||||
find_library(IOKIT_LIBRARY IOKit REQUIRED)
|
||||
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
||||
find_library(METAL_LIBRARY Metal REQUIRED)
|
||||
find_library(QUARTZCORE_LIBRARY QuartzCore REQUIRED)
|
||||
|
||||
# SPIRV-Cross
|
||||
option(SPIRV_CROSS_CLI "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_TESTS "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_HLSL "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_CPP "" OFF)
|
||||
option(SPIRV_CROSS_SKIP_INSTALL "" ON)
|
||||
add_subdirectory(SPIRV-Cross)
|
||||
|
||||
# Common
|
||||
set(MVK_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Common)
|
||||
file(GLOB_RECURSE MVK_COMMON_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_COMMON_DIR}/*.cpp
|
||||
${MVK_COMMON_DIR}/*.m
|
||||
${MVK_COMMON_DIR}/*.mm)
|
||||
set(MVK_COMMON_INCLUDES ${MVK_COMMON_DIR})
|
||||
|
||||
add_library(MoltenVKCommon STATIC ${MVK_COMMON_SOURCES})
|
||||
target_include_directories(MoltenVKCommon PUBLIC ${MVK_COMMON_INCLUDES})
|
||||
target_compile_options(MoltenVKCommon PRIVATE -w)
|
||||
|
||||
# MoltenVKShaderConverter
|
||||
set(MVK_SHADER_CONVERTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKShaderConverter)
|
||||
file(GLOB_RECURSE MVK_SHADER_CONVERTER_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.cpp
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.m
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.mm)
|
||||
set(MVK_SHADER_CONVERTER_INCLUDES ${MVK_SHADER_CONVERTER_DIR} ${MVK_SHADER_CONVERTER_DIR}/include)
|
||||
|
||||
add_library(MoltenVKShaderConverter STATIC ${MVK_SHADER_CONVERTER_SOURCES})
|
||||
target_include_directories(MoltenVKShaderConverter PUBLIC ${MVK_SHADER_CONVERTER_INCLUDES})
|
||||
target_compile_options(MoltenVKShaderConverter PRIVATE -w)
|
||||
target_link_libraries(MoltenVKShaderConverter PRIVATE spirv-cross-msl spirv-cross-reflect MoltenVKCommon)
|
||||
target_compile_definitions(MoltenVKShaderConverter PRIVATE MVK_EXCLUDE_SPIRV_TOOLS=1)
|
||||
|
||||
# MoltenVK
|
||||
set(MVK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK)
|
||||
file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_DIR}/MoltenVK/*.cpp
|
||||
${MVK_DIR}/MoltenVK/*.m
|
||||
${MVK_DIR}/MoltenVK/*.mm)
|
||||
file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*)
|
||||
set(MVK_INCLUDES
|
||||
${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include
|
||||
${UNLEASHED_RECOMP_THIRDPARTY_ROOT}/plume/contrib/Vulkan-Headers/include)
|
||||
|
||||
add_library(MoltenVK SHARED ${MVK_SOURCES})
|
||||
target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES})
|
||||
target_compile_options(MoltenVK PRIVATE -w)
|
||||
target_link_libraries(MoltenVK PRIVATE
|
||||
${APPKIT_LIBRARY} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY}
|
||||
spirv-cross-msl MoltenVKCommon MoltenVKShaderConverter)
|
||||
target_compile_definitions(MoltenVK PRIVATE MVK_FRAMEWORK_VERSION=${MVK_VERSION} MVK_USE_CEREAL=0)
|
||||
1
thirdparty/MoltenVK/MoltenVK
vendored
Submodule
1
thirdparty/MoltenVK/MoltenVK
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3a0b07a24a4a681ffe70b461b1f4333b2729e2ef
|
||||
1
thirdparty/MoltenVK/SPIRV-Cross
vendored
Submodule
1
thirdparty/MoltenVK/SPIRV-Cross
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 22b22f5685d868828be01c9ac00c31902e60afd9
|
||||
1
thirdparty/Vulkan-Headers
vendored
1
thirdparty/Vulkan-Headers
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 14345dab231912ee9601136e96ca67a6e1f632e7
|
||||
1
thirdparty/VulkanMemoryAllocator
vendored
1
thirdparty/VulkanMemoryAllocator
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39
|
||||
1
thirdparty/plume
vendored
Submodule
1
thirdparty/plume
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit fffeb35f836d8c945697ec82b735e77db401e2de
|
||||
1
thirdparty/volk
vendored
1
thirdparty/volk
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 447e21b5d92ed8d5271b0d39b071f938fcfa875f
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit c017eb630ab917bffd3bc6a0a46995b49e7d8049
|
||||
Subproject commit c5bfd90d87f2ed0db8cff5c19ea3aff0e161e527
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 56738e5893ed7c4dc108996590475c52726623e3
|
||||
Subproject commit 990d03b28a27b50277ee5d8d942e1c5f873869d1
|
||||
|
|
@ -9,8 +9,12 @@
|
|||
"name": "directx12-agility",
|
||||
"platform": "windows"
|
||||
},
|
||||
"directx-dxc",
|
||||
"freetype",
|
||||
"curl"
|
||||
],
|
||||
"vcpkg-configuration": {
|
||||
"overlay-triplets": [
|
||||
"vcpkg/triplets"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
vcpkg/triplets/arm64-osx.cmake
Normal file
7
vcpkg/triplets/arm64-osx.cmake
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE static)
|
||||
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||
set(VCPKG_OSX_ARCHITECTURES arm64)
|
||||
set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0")
|
||||
7
vcpkg/triplets/x64-osx.cmake
Normal file
7
vcpkg/triplets/x64-osx.cmake
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||
set(VCPKG_CRT_LINKAGE dynamic)
|
||||
set(VCPKG_LIBRARY_LINKAGE static)
|
||||
|
||||
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||
set(VCPKG_OSX_ARCHITECTURES x86_64)
|
||||
set(VCPKG_OSX_DEPLOYMENT_TARGET "13.0")
|
||||
Loading…
Add table
Reference in a new issue