28 Commits
Author SHA1 Message Date
goeiecool9999andGitHub e9d10a9581 Linux+OpenGL: Implement GUI vsync setting (#477) 2022-11-13 08:29:25 +01:00
goeiecool9999andGitHub 2842615edb Fix various colour values for dark themes (#439) 2022-11-13 08:27:09 +01:00
qurious-pixelandGitHub 94b179ef5a [APPIMAGE] Update AppImage (#481)
- include libthai.so.0
- set LC_ALL
2022-11-12 07:38:52 +01:00
jn64andGitHub 7f21104b54 Disable Discord RPC checkbox based on build option (#476) 2022-11-11 20:51:50 +01:00
goeiecool9999andGitHub bbd8d6d5ac Linux OpenGL: Fix gamepad not updating (#474) 2022-11-11 08:33:44 +01:00
goeiecool9999andGitHub 4d68446f14 Vulkan: Further swapchain code improvements. (#473) 2022-11-11 08:14:38 +01:00
goeiecool9999andGitHub a0e69ffbbd Linux: Explicitly enable some flags related to security. (#446) 2022-11-09 07:17:50 +01:00
c3d6cad428 Added a note on re-building to fix RPATH issues. (#352)
Co-authored-by: Exzap <13877693+Exzap@users.noreply.github.com>
2022-11-09 04:22:09 +01:00
UltraHDRandGitHub 58c7b56c60 Add Apple Silicon build instructions (#280) 2022-11-09 02:47:23 +01:00
bslhqandGitHub be287a1f4e ImGui: match all begin()/end() (#470) 2022-11-09 02:45:40 +01:00
TillsunsetandGitHub 5adb1e9618 Add commit hash to build name on build check workflow (#463) 2022-11-07 02:47:59 +01:00
goeiecool9999andGitHub 138510106c Vulkan: Fix freeze when closing pad view (#435) 2022-11-06 00:40:00 +01:00
Exzap 948460cad7 InputSettings: Refresh panels on profile load and other operations 2022-11-06 00:32:33 +01:00
Exzap 3df8217a02 SDLController: Do not manually recycle controller instance
SDL_GameControllerFromInstanceID does not increase internal ref counter.
Fixes a crash when removing an SDL controller that is in use by another profile
2022-11-06 00:32:33 +01:00
Exzap ec6726e85c Use generic EC_POINT_get_affine_coordinates 2022-11-06 00:32:33 +01:00
goeiecool9999andGitHub 348d86648f Vulkan: Refactor swapchain code (#399) 2022-11-04 15:22:29 +01:00
ExzapandGitHub 592c9b2776 Update build_check.yml 2022-11-04 15:09:25 +01:00
qurious-pixelandGitHub 5d156672e8 CI: Add AppImage Build (#452) 2022-11-04 15:07:17 +01:00
TillsunsetandGitHub 2f86622a68 Don't go to mount point for free space check (#450) 2022-11-04 14:34:32 +01:00
ExzapandGitHub a40b226e00 CubebInput: Avoid redundant CoInitializeEx (#449) 2022-11-03 18:29:21 +01:00
TillsunsetandGitHub 521f2fb707 MacOS: Workaround for Metal stride limitation (#445) 2022-11-03 12:51:32 +01:00
goeiecool9999andGitHub a129d22a57 Vulkan: Experimental fix for self-dependency barriers during renderpass (#431) 2022-11-03 00:43:26 +01:00
Adrian GraberandGitHub d4e14d2b05 Implement proper microphone support (#251) 2022-11-03 00:24:34 +01:00
goeiecool9999andGitHub dfa7774c4c Non-windows: Link fontawesome into executable. (#442) 2022-11-03 00:23:31 +01:00
goeiecool9999andGitHub c3182aedd9 GeneralSettings: Update vsync after settings close (#401) 2022-10-31 17:54:26 +01:00
Zhaohui ShiandGitHub f41f7b63e8 DSUController: fix crash when running on offline mode (#434) 2022-10-31 14:27:35 +01:00
TillsunsetandGitHub c143950dd1 Fix fullscreen on macos (#429) 2022-10-30 01:40:53 +02:00
jn64andGitHub 4e991d603a Add libpulse-dev to CI build (#430) 2022-10-30 01:39:39 +02:00
59 changed files with 2013 additions and 835 deletions
+38 -14
View File
@@ -22,34 +22,36 @@ jobs:
uses: actions/checkout@v3
with:
submodules: "recursive"
- name: Setup release mode parameters (for deploy)
if: ${{ inputs.deploymode == 'release' }}
run: |
echo "BUILD_MODE=release" >> $GITHUB_ENV
echo "BUILD_FLAGS=" >> $GITHUB_ENV
echo "Build mode is release"
- name: Setup debug mode parameters (for continous build)
if: ${{ inputs.deploymode != 'release' }}
run: |
echo "BUILD_MODE=debug" >> $GITHUB_ENV
echo "BUILD_FLAGS=" >> $GITHUB_ENV
echo "Build mode is debug"
- name: Setup version for experimental
if: ${{ inputs.experimentalversion != '' }}
run: |
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y ninja-build cmake libgtk-3-dev libsecret-1-dev libgcrypt20-dev libsystemd-dev freeglut3-dev clang-12 nasm
sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build
- name: "Bootstrap vcpkg"
run: |
bash ./dependencies/vcpkg/bootstrap-vcpkg.sh
- name: 'Setup NuGet Credentials for vcpkg'
shell: 'bash'
run: |
@@ -66,15 +68,12 @@ jobs:
- name: "cmake"
run: |
mkdir -p build
cd build
cmake .. ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja
cmake -S . -B build ${{ env.BUILD_FLAGS }} -DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} -DPORTABLE=OFF -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja
- name: "Build Cemu"
run: |
cd build
ninja
cmake --build build
- name: Prepare artifact
if: ${{ inputs.deploymode == 'release' }}
run: mv bin/Cemu_release bin/Cemu
@@ -85,8 +84,33 @@ jobs:
with:
name: cemu-bin-linux-x64
path: ./bin/Cemu
build-appimage:
runs-on: ubuntu-20.04
needs: build-ubuntu
steps:
- name: Checkout Upstream Repo
uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: cemu-bin-linux-x64
path: bin
- name: "Install system dependencies"
run: |
sudo apt update -qq
sudo apt install -y clang-12 cmake freeglut3-dev libgcrypt20-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build
- name: "Build AppImage"
run: dist/linux/appimage.sh
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: cemu-appimage-x64
path: artifacts
build-windows:
runs-on: windows-2022
steps:
@@ -239,4 +263,4 @@ jobs:
if: ${{ inputs.deploymode == 'release' }}
with:
name: cemu-bin-macos-x64
path: ./bin/Cemu.dmg
path: ./bin/Cemu.dmg
@@ -13,13 +13,18 @@ jobs:
runs-on: ubuntu-20.04
needs: call-release-build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: cemu-bin-linux-x64
path: cemu-bin-linux-x64
- uses: actions/download-artifact@v3
with:
name: cemu-appimage-x64
path: cemu-appimage-x64
- uses: actions/download-artifact@v3
with:
name: cemu-bin-windows-x64
@@ -53,7 +58,14 @@ jobs:
mv cemu-bin-windows-x64/Cemu.exe ./${{ env.CEMU_FOLDER_NAME }}/Cemu.exe
zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-windows-x64.zip ${{ env.CEMU_FOLDER_NAME }}
rm -r ./${{ env.CEMU_FOLDER_NAME }}
- name: Create appimage
run: |
VERSION=${{ env.CEMU_VERSION }}
echo "Cemu Version is $VERSION"
ls cemu-appimage-x64
mv cemu-appimage-x64/Cemu-*-x86_64.AppImage upload/Cemu-$VERSION-x86_64.AppImage
- name: Create release from linux-bin
run: |
ls ./
+14 -6
View File
@@ -15,13 +15,18 @@ jobs:
runs-on: ubuntu-20.04
needs: call-release-build
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: cemu-bin-linux-x64
path: cemu-bin-linux-x64
- uses: actions/download-artifact@v3
with:
name: cemu-appimage-x64
path: cemu-appimage-x64
- uses: actions/download-artifact@v3
with:
name: cemu-bin-windows-x64
@@ -44,11 +49,7 @@ jobs:
echo "Cemu CI version: $(./getversion)"
echo "CEMU_FOLDER_NAME=Cemu_$(./getversion)" >> $GITHUB_ENV
echo "CEMU_VERSION=$(./getversion)" >> $GITHUB_ENV
- name: Create appimage
run: |
echo "to do"
- name: Create release from windows-bin
run: |
ls ./
@@ -57,6 +58,13 @@ jobs:
mv cemu-bin-windows-x64/Cemu.exe ./${{ env.CEMU_FOLDER_NAME }}/Cemu.exe
zip -9 -r upload/cemu-${{ env.CEMU_VERSION }}-windows-x64.zip ${{ env.CEMU_FOLDER_NAME }}
rm -r ./${{ env.CEMU_FOLDER_NAME }}
- name: Create appimage
run: |
VERSION=${{ env.CEMU_VERSION }}
echo "Cemu Version is $VERSION"
ls cemu-appimage-x64
mv cemu-appimage-x64/Cemu-*-x86_64.AppImage upload/Cemu-$VERSION-x86_64.AppImage
- name: Create release from ubuntu-bin
run: |
+1
View File
@@ -13,6 +13,7 @@
*.out
*.app
.vs
.vscode
.idea/
build/
+20 -9
View File
@@ -25,7 +25,7 @@ To compile Cemu, a recent enough compiler and STL with C++20 support is required
### Installing dependencies
#### For Ubuntu and derivatives:
`sudo apt install -y git curl cmake ninja-build nasm libgtk-3-dev libsecret-1-dev libgcrypt20-dev libsystemd-dev freeglut3-dev libpulse-dev`
`sudo apt install -y cmake curl freeglut3-dev git libgcrypt20-dev libgtk-3-dev libpulse-dev libsecret-1-dev libsystemd-dev nasm ninja-build`
*Additionally, for Ubuntu 22.04 only:*
- `sudo apt install -y clang-12`
@@ -33,10 +33,10 @@ To compile Cemu, a recent enough compiler and STL with C++20 support is required
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-12 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-12 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`
#### For Arch and derivatives:
`sudo pacman -S --needed git cmake llvm clang ninja nasm base-devel linux-headers gtk3 libsecret libgcrypt systemd freeglut zip unzip libpulse`
`sudo pacman -S --needed base-devel clang cmake freeglut git gtk3 libgcrypt libpulse libsecret linux-headers llvm nasm ninja systemd unzip zip`
#### For Fedora and derivatives:
`sudo dnf install git cmake clang ninja-build nasm kernel-headers gtk3-devel libsecret-devel libgcrypt-devel systemd-devel freeglut-devel perl-core zlib-devel cubeb-devel`
`sudo dnf install clang cmake cubeb-devel freeglut-devel git gtk3-devel kernel-headers libgcrypt-devel libsecret-devel nasm ninja-build perl-core systemd-devel zlib-devel`
### Build Cemu using cmake and clang
1. `git clone --recursive https://github.com/cemu-project/Cemu`
@@ -57,21 +57,32 @@ You can use it by replacing the step 3 with the following:
- If step 3 is still failing or if you're not able to find the cause, please make an issue on our Github about it!
- If step 4 gives you an error that contains something like `main.cpp.o: in function 'std::__cxx11::basic_string...`, you likely are experiencing a clang-14 issue. This can only be fixed by either lowering the clang version or using GCC, see below.
- If step 4 gives you a different error, you could report it to this repo or try using GCC. Just make sure your standard library and compilers are updated since Cemu uses a lot of modern features!
- If step 4 gives you undefined libdecor_xx, you are likely experiencing an issue with sdl2 package that comes with vcpkg. Delete sdl2 from vcpkg.json in source file and recompile.
- If step 4 gives you undefined libdecor_xx, you are likely experiencing an issue with sdl2 package that comes with vcpkg. Delete sdl2 from vcpkg.json in source file and recompile.
- If step 3 fails during rebuild after `git pull` with an error that mentions RPATH, add this to the end of step 3: `-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON`
## MacOS
## macOS
To compile Cemu, a recent enough compiler and STL with C++20 support is required! LLVM 13 and
below, built in LLVM, and Xcode LLVM don't support the C++20 feature set required. Currently,
LLVM 15 isn't supported due to compatibility issues with Boost dependency. The OpenGL graphics
API isn't support on MacOS, Vulkan must be used. Additionally Vulkan must be used through the
Molten-VK compatibility layer.
API isn't support on macOS, Vulkan must be used. Additionally Vulkan must be used through the
Molten-VK compatibility layer
### On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used
You can skip this section if you have an Intel Mac. Every time you compile, you need to perform steps 2.
1. `softwareupdate --install-rosetta` # Install Rosetta 2 if you don't have it. This only has to be done once
2. `arch -x86_64 zsh` # run an x64 shell
### Installing brew
`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
1. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
2. `eval "$(/usr/local/Homebrew/bin/brew shellenv)"` # set x86_64 brew env
### Installing dependencies
`brew install git cmake llvm@14 ninja nasm molten-vk`
`brew install boost git cmake llvm@14 ninja nasm molten-vk`
### Build Cemu using cmake and clang
1. `git clone --recursive https://github.com/cemu-project/Cemu`
+8 -1
View File
@@ -6,7 +6,14 @@ option(MACOS_BUNDLE "The executable when built on macOS will be created as an ap
set(EXPERIMENTAL_VERSION "" CACHE STRING "") # used by CI script to set experimental version
if (EXPERIMENTAL_VERSION)
add_definitions(-DEMULATOR_VERSION_MINOR=${EXPERIMENTAL_VERSION})
add_definitions(-DEMULATOR_VERSION_MINOR=${EXPERIMENTAL_VERSION})
execute_process(
COMMAND git log --format=%h -1
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
endif()
if (ENABLE_VCPKG)
Vendored Executable
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
if [ -z "${GITHUB_WORKSPACE}" ]; then
export GITHUB_WORKSPACE="."
fi
curl -sSfLO "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
chmod a+x linuxdeploy*.AppImage
curl -sSfL https://github.com$(curl https://github.com/probonopd/go-appimage/releases/expanded_assets/continuous | grep "mkappimage-.*-x86_64.AppImage" | head -n 1 | cut -d '"' -f 2) -o mkappimage.AppImage
chmod a+x mkappimage.AppImage
curl -sSfLO "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
chmod a+x linuxdeploy-plugin-gtk.sh
if [[ ! -e /usr/lib/x86_64-linux-gnu ]]; then
sed -i 's#lib\/x86_64-linux-gnu#lib64#g' linuxdeploy-plugin-gtk.sh
fi
mkdir -p AppDir/usr/
cp dist/linux/{info.cemu.Cemu.desktop,info.cemu.Cemu.png} AppDir/
mkdir -p AppDir/usr/share/applications
mkdir -p AppDir/usr/share/icons/hicolor/scalable/apps
mkdir -p AppDir/usr/lib
cp -r bin AppDir/usr/
cp /usr/lib/x86_64-linux-gnu/{libsepol.so.1,libffi.so.7,libpcre.so.3,libGLU.so.1,libthai.so.0} AppDir/usr/lib
chmod +x AppDir/usr/bin/Cemu
#chmod +x AppDir/AppRun
export UPD_INFO="gh-releases-zsync|cemu-project|Cemu|ci|Cemu.AppImage.zsync"
./linuxdeploy-x86_64.AppImage --appimage-extract-and-run\
--appdir="$GITHUB_WORKSPACE"/AppDir/ \
-d "$GITHUB_WORKSPACE"/AppDir/info.cemu.Cemu.desktop \
-i "$GITHUB_WORKSPACE"/AppDir/info.cemu.Cemu.png \
-e "$GITHUB_WORKSPACE"/AppDir/usr/bin/Cemu \
--plugin gtk
GITVERSION=$(git rev-parse --short HEAD)
echo $GITVERSION
if [[ -z ${GITVERSION} ]]; then
GITVERSION=experimental
fi
echo "Cemu Version Cemu-${GITVERSION}"
rm AppDir/usr/lib/libwayland-client.so.0
echo "export LC_ALL=C" >> AppDir/apprun-hooks/linuxdeploy-plugin-gtk.sh
VERSION=${GITVERSION} ./mkappimage.AppImage --appimage-extract-and-run "$GITHUB_WORKSPACE"/AppDir
mkdir -p "$GITHUB_WORKSPACE"/artifacts/
mv Cemu-${GITVERSION}-x86_64.AppImage "$GITHUB_WORKSPACE"/artifacts/
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

+7
View File
@@ -34,6 +34,13 @@ elseif(UNIX)
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_compile_options(-Wno-ambiguous-reversed-operator)
endif()
# most linux environments should enable pie by default, but make sure just in case.
# the same cannot be said for no executable stack which some linkers
# and configurations thereof might enable due to the assembly in the project
if(NOT APPLE)
add_compile_options(-fpie)
add_link_options(-pie -z noexecstack)
endif()
add_compile_options(-Wno-multichar -Wno-invalid-offsetof -Wno-switch -Wno-ignored-attributes -Wno-deprecated-enum-enum-conversion)
endif()
+2
View File
@@ -178,6 +178,8 @@ add_library(CemuCafe
HW/Latte/Renderer/Vulkan/LatteTextureVk.h
HW/Latte/Renderer/Vulkan/RendererShaderVk.cpp
HW/Latte/Renderer/Vulkan/RendererShaderVk.h
HW/Latte/Renderer/Vulkan/SwapchainInfoVk.cpp
HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h
HW/Latte/Renderer/Vulkan/TextureReadbackVk.cpp
HW/Latte/Renderer/Vulkan/VKRBase.h
HW/Latte/Renderer/Vulkan/VKRMemoryManager.cpp
+2
View File
@@ -5,6 +5,7 @@
#include "Cafe/HW/Espresso/Interpreter/PPCInterpreterInternal.h"
#include "Cafe/HW/Espresso/Recompiler/PPCRecompiler.h"
#include "audio/IAudioAPI.h"
#include "audio/IAudioInputAPI.h"
#include "Cafe/HW/Espresso/Debugger/Debugger.h"
#include "config/ActiveSettings.h"
@@ -402,6 +403,7 @@ void cemu_initForGame()
GraphicPack2::ActivateForCurrentTitle();
// print audio log
IAudioAPI::PrintLogging();
IAudioInputAPI::PrintLogging();
// everything initialized
forceLog_printf("------- Run title -------");
// wait till GPU thread is initialized
+8 -11
View File
@@ -123,8 +123,8 @@ void LatteOverlay_renderOverlay(ImVec2& position, ImVec2& pivot, sint32 directio
g_renderer->AppendOverlayDebugInfo();
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
ImGui::PopStyleColor();
@@ -170,8 +170,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
ImGui::TextUnformatted(s_mii_name.c_str());
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
// controller
std::vector<std::pair<int, std::string>> profiles;
@@ -209,8 +209,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
else
s_init_overlay = true;
@@ -254,10 +254,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
}
@@ -306,8 +304,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
}
@@ -363,8 +361,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
}
@@ -435,8 +433,8 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
#endif
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
}
}
@@ -475,10 +473,9 @@ void LatteOverlay_RenderNotifications(ImVec2& position, ImVec2& pivot, sint32 di
}
position.y += (ImGui::GetWindowSize().y + 10.0f) * direction;
ImGui::End();
}
ImGui::End();
}
ImGui::PopStyleColor();
ImGui::PopFont();
}
+17 -19
View File
@@ -350,10 +350,10 @@ void LatteShaderCache_load()
ImGui::GetWindowDrawList()->AddImage(g_shaderCacheLoaderState.textureTVId, ImVec2(paddingLeftAndRight, paddingTopAndBottom), ImVec2(io.DisplaySize.x-paddingLeftAndRight, io.DisplaySize.y-paddingTopAndBottom), { 0,1 }, { 1,0 });
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
g_renderer->BeginFrame(false);
@@ -365,7 +365,7 @@ void LatteShaderCache_load()
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0,0 });
if (ImGui::Begin("Background texture2", nullptr, kPopupFlags))
{
{
if (g_shaderCacheLoaderState.textureDRCId)
{
float imageDisplayWidth = io.DisplaySize.x;
@@ -383,11 +383,11 @@ void LatteShaderCache_load()
ImGui::GetWindowDrawList()->AddImage(g_shaderCacheLoaderState.textureDRCId, ImVec2(paddingLeftAndRight, paddingTopAndBottom), ImVec2(io.DisplaySize.x-paddingLeftAndRight, io.DisplaySize.y-paddingTopAndBottom), { 0,1 }, { 1,0 });
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
}
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
g_renderer->SwapBuffers(true, true);
}
@@ -452,8 +452,8 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
}
ImGui::GetWindowDrawList()->AddImage(g_shaderCacheLoaderState.textureTVId, ImVec2(paddingLeftAndRight, paddingTopAndBottom), ImVec2(io.DisplaySize.x-paddingLeftAndRight, io.DisplaySize.y-paddingTopAndBottom), { 0,1 }, { 1,0 });
ImGui::End();
}
ImGui::End();
ImGui::PopStyleVar(2);
}
@@ -502,8 +502,8 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
text = fmt::format("{}/{} ({}%)", g_shaderCacheLoaderState.loadedShaderFiles, g_shaderCacheLoaderState.shaderFileCount, (int)(percentLoaded * 100));
ImGui::SetCursorPosX(width - ImGui::CalcTextSize(text.c_str()).x / 2);
ImGui::Text("%s", text.c_str());
ImGui::End();
}
ImGui::End();
ImGui::PopFont();
ImGui::PopStyleColor(2);
@@ -529,13 +529,11 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
ImGui::Text("Geometry shaders");
ImGui::SameLine(offset);
ImGui::Text("%d", shaderCacheScreenStats.geometryShaderCount);
ImGui::End();
}
ImGui::End();
ImGui::PopStyleColor();
ImGui::PopFont();
}
g_renderer->ImguiEnd();
lastFrameUpdate = tick_cached();
}
@@ -565,11 +563,11 @@ void LatteShaderCache_ShowProgress(const std::function <bool(void)>& loadUpdateF
}
ImGui::GetWindowDrawList()->AddImage(g_shaderCacheLoaderState.textureDRCId, ImVec2(paddingLeftAndRight, paddingTopAndBottom), ImVec2(io.DisplaySize.x-paddingLeftAndRight, io.DisplaySize.y-paddingTopAndBottom), { 0,1 }, { 1,0 });
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
}
}
ImGui::End();
ImGui::PopStyleVar(2);
g_renderer->ImguiEnd();
}
// finish frame
g_renderer->SwapBuffers(true, true);
@@ -25,8 +25,10 @@
#define STRINGIFY(X) STRINGIFY2(X)
#define GLFUNC(__type, __name) __type __name;
#define EGLFUNC(__type, __name) __type __name;
#include "Common/GLInclude/glFunctions.h"
#undef GLFUNC
#undef EGLFUNC
#include "config/ActiveSettings.h"
#include "config/LaunchSettings.h"
@@ -229,9 +231,17 @@ void LoadOpenGLImports()
_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC)dlsym(libGL, "glXGetProcAddressARB");
}
void* libEGL = dlopen("libEGL.so.1", RTLD_NOW | RTLD_GLOBAL);
if(!libEGL)
{
libGL = dlopen("libEGL.so", RTLD_NOW | RTLD_GLOBAL);
}
#define GLFUNC(__type, __name) __name = (__type)_GetOpenGLFunction(libGL, _glXGetProcAddress, STRINGIFY(__name));
#define EGLFUNC(__type, __name) __name = (__type)dlsym(libEGL, STRINGIFY(__name));
#include "Common/GLInclude/glFunctions.h"
#undef GLFUNC
#undef EGLFUNC
}
#elif BOOST_OS_MACOS
void LoadOpenGLImports()
@@ -352,15 +362,6 @@ void OpenGLRenderer::NotifyLatteCommandProcessorIdle()
glFlush();
}
void OpenGLRenderer::EnableVSync(int state)
{
#if BOOST_OS_WINDOWS
if(wglSwapIntervalEXT)
wglSwapIntervalEXT(state); // 1 = enabled, 0 = disabled
#else
cemuLog_log(LogType::Force, "OpenGL vsync not implemented");
#endif
}
bool IsRunningInWine();
@@ -30,7 +30,7 @@ public:
void Flush(bool waitIdle = false) override;
void NotifyLatteCommandProcessorIdle() override;
void EnableVSync(int state) override;
void UpdateVSyncState();
void EnableDebugMode() override;
void SwapBuffers(bool swapTV = true, bool swapDRC = true) override;
@@ -282,4 +282,4 @@ private:
std::vector<bufferCacheReleaseQueueEntry_t> bufferCacheEntries;
}m_destructionQueues;
};
};
+1 -2
View File
@@ -58,7 +58,6 @@ public:
virtual bool GetVRAMInfo(int& usageInMB, int& totalInMB) const;
virtual void EnableDebugMode() {}
virtual void EnableVSync(int state) = 0;
virtual void ClearColorbuffer(bool padView) = 0;
virtual void DrawEmptyFrame(bool mainWindow) = 0;
@@ -176,4 +175,4 @@ protected:
#endif
};
extern std::unique_ptr<Renderer> g_renderer;
extern std::unique_ptr<Renderer> g_renderer;
@@ -0,0 +1,365 @@
#include "SwapchainInfoVk.h"
#include "config/CemuConfig.h"
#include "Cafe/HW/Latte/Core/Latte.h"
#include "Cafe/HW/Latte/Core/LatteTiming.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
void SwapchainInfoVk::Create(VkPhysicalDevice physicalDevice, VkDevice logicalDevice)
{
m_physicalDevice = physicalDevice;
m_logicalDevice = logicalDevice;
const auto details = QuerySwapchainSupport(surface, physicalDevice);
m_surfaceFormat = ChooseSurfaceFormat(details.formats);
m_actualExtent = ChooseSwapExtent(details.capabilities);
// calculate number of swapchain presentation images
uint32_t image_count = details.capabilities.minImageCount + 1;
if (details.capabilities.maxImageCount > 0 && image_count > details.capabilities.maxImageCount)
image_count = details.capabilities.maxImageCount;
VkSwapchainCreateInfoKHR create_info = CreateSwapchainCreateInfo(surface, details, m_surfaceFormat, image_count, m_actualExtent);
create_info.oldSwapchain = nullptr;
create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
VkResult result = vkCreateSwapchainKHR(logicalDevice, &create_info, nullptr, &swapchain);
if (result != VK_SUCCESS)
UnrecoverableError("Error attempting to create a swapchain");
result = vkGetSwapchainImagesKHR(logicalDevice, swapchain, &image_count, nullptr);
if (result != VK_SUCCESS)
UnrecoverableError("Error attempting to retrieve the count of swapchain images");
m_swapchainImages.resize(image_count);
result = vkGetSwapchainImagesKHR(logicalDevice, swapchain, &image_count, m_swapchainImages.data());
if (result != VK_SUCCESS)
UnrecoverableError("Error attempting to retrieve swapchain images");
// create default renderpass
VkAttachmentDescription colorAttachment = {};
colorAttachment.format = m_surfaceFormat.format;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachmentRef = {};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
result = vkCreateRenderPass(logicalDevice, &renderPassInfo, nullptr, &m_swapchainRenderPass);
if (result != VK_SUCCESS)
UnrecoverableError("Failed to create renderpass for swapchain");
// create swapchain image views
m_swapchainImageViews.resize(m_swapchainImages.size());
for (sint32 i = 0; i < m_swapchainImages.size(); i++)
{
VkImageViewCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = m_swapchainImages[i];
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = m_surfaceFormat.format;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
result = vkCreateImageView(logicalDevice, &createInfo, nullptr, &m_swapchainImageViews[i]);
if (result != VK_SUCCESS)
UnrecoverableError("Failed to create imageviews for swapchain");
}
// create swapchain framebuffers
m_swapchainFramebuffers.resize(m_swapchainImages.size());
for (size_t i = 0; i < m_swapchainImages.size(); i++)
{
VkImageView attachments[1];
attachments[0] = m_swapchainImageViews[i];
// create framebuffer
VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = m_swapchainRenderPass;
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = m_actualExtent.width;
framebufferInfo.height = m_actualExtent.height;
framebufferInfo.layers = 1;
result = vkCreateFramebuffer(logicalDevice, &framebufferInfo, nullptr, &m_swapchainFramebuffers[i]);
if (result != VK_SUCCESS)
UnrecoverableError("Failed to create framebuffer for swapchain");
}
m_swapchainPresentSemaphores.resize(m_swapchainImages.size());
// create present semaphore
VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
for (auto& semaphore : m_swapchainPresentSemaphores){
if (vkCreateSemaphore(logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
UnrecoverableError("Failed to create semaphore for swapchain present");
}
m_acquireSemaphores.resize(m_swapchainImages.size());
for (auto& semaphore : m_acquireSemaphores)
{
VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
if (vkCreateSemaphore(logicalDevice, &info, nullptr, &semaphore) != VK_SUCCESS)
UnrecoverableError("Failed to create semaphore for swapchain acquire");
}
m_acquireIndex = 0;
VkFenceCreateInfo fenceInfo = {};
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
result = vkCreateFence(logicalDevice, &fenceInfo, nullptr, &m_imageAvailableFence);
if (result != VK_SUCCESS)
UnrecoverableError("Failed to create fence for swapchain");
}
void SwapchainInfoVk::Cleanup()
{
m_swapchainImages.clear();
for (auto& sem: m_swapchainPresentSemaphores)
vkDestroySemaphore(m_logicalDevice, sem, nullptr);
m_swapchainPresentSemaphores.clear();
for (auto& itr: m_acquireSemaphores)
vkDestroySemaphore(m_logicalDevice, itr, nullptr);
m_acquireSemaphores.clear();
if (m_swapchainRenderPass)
{
vkDestroyRenderPass(m_logicalDevice, m_swapchainRenderPass, nullptr);
m_swapchainRenderPass = nullptr;
}
for (auto& imageView : m_swapchainImageViews)
vkDestroyImageView(m_logicalDevice, imageView, nullptr);
m_swapchainImageViews.clear();
for (auto& framebuffer : m_swapchainFramebuffers)
vkDestroyFramebuffer(m_logicalDevice, framebuffer, nullptr);
m_swapchainFramebuffers.clear();
if (m_imageAvailableFence)
{
vkDestroyFence(m_logicalDevice, m_imageAvailableFence, nullptr);
m_imageAvailableFence = nullptr;
}
if (swapchain)
{
vkDestroySwapchainKHR(m_logicalDevice, swapchain, nullptr);
swapchain = VK_NULL_HANDLE;
}
}
bool SwapchainInfoVk::IsValid() const
{
return swapchain && m_imageAvailableFence;
}
void SwapchainInfoVk::UnrecoverableError(const char* errMsg)
{
forceLog_printf("Unrecoverable error in Vulkan swapchain");
forceLog_printf("Msg: %s", errMsg);
throw std::runtime_error(errMsg);
}
SwapchainInfoVk::QueueFamilyIndices SwapchainInfoVk::FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device)
{
uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
QueueFamilyIndices indices;
for (int i = 0; i < (int)queueFamilies.size(); ++i)
{
const auto& queueFamily = queueFamilies[i];
if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)
indices.graphicsFamily = i;
VkBool32 presentSupport = false;
const VkResult result = vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &presentSupport);
if (result != VK_SUCCESS)
throw std::runtime_error(fmt::format("Error while attempting to check if a surface supports presentation: {}", result));
if (queueFamily.queueCount > 0 && presentSupport)
indices.presentFamily = i;
if (indices.IsComplete())
break;
}
return indices;
}
SwapchainInfoVk::SwapchainSupportDetails SwapchainInfoVk::QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device)
{
SwapchainSupportDetails details;
VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities);
if (result != VK_SUCCESS)
{
if (result != VK_ERROR_SURFACE_LOST_KHR)
forceLog_printf("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed. Error %d", (sint32)result);
throw std::runtime_error(fmt::format("Unable to retrieve physical device surface capabilities: {}", result));
}
uint32_t formatCount = 0;
result = vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, nullptr);
if (result != VK_SUCCESS)
{
forceLog_printf("vkGetPhysicalDeviceSurfaceFormatsKHR failed. Error %d", (sint32)result);
throw std::runtime_error(fmt::format("Unable to retrieve the number of formats for a surface on a physical device: {}", result));
}
if (formatCount != 0)
{
details.formats.resize(formatCount);
result = vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, details.formats.data());
if (result != VK_SUCCESS)
{
forceLog_printf("vkGetPhysicalDeviceSurfaceFormatsKHR failed. Error %d", (sint32)result);
throw std::runtime_error(fmt::format("Unable to retrieve the formats for a surface on a physical device: {}", result));
}
}
uint32_t presentModeCount = 0;
result = vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, nullptr);
if (result != VK_SUCCESS)
{
forceLog_printf("vkGetPhysicalDeviceSurfacePresentModesKHR failed. Error %d", (sint32)result);
throw std::runtime_error(fmt::format("Unable to retrieve the count of present modes for a surface on a physical device: {}", result));
}
if (presentModeCount != 0)
{
details.presentModes.resize(presentModeCount);
result = vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, details.presentModes.data());
if (result != VK_SUCCESS)
{
forceLog_printf("vkGetPhysicalDeviceSurfacePresentModesKHR failed. Error %d", (sint32)result);
throw std::runtime_error(fmt::format("Unable to retrieve the present modes for a surface on a physical device: {}", result));
}
}
return details;
}
VkSurfaceFormatKHR SwapchainInfoVk::ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& formats) const
{
if (formats.size() == 1 && formats[0].format == VK_FORMAT_UNDEFINED)
return{ VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
for (const auto& format : formats)
{
bool useSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
if (useSRGB)
{
if (format.format == VK_FORMAT_B8G8R8A8_SRGB && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return format;
}
else
{
if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
return format;
}
}
return formats[0];
}
VkExtent2D SwapchainInfoVk::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const
{
if (capabilities.currentExtent.width != std::numeric_limits<uint32>::max())
return capabilities.currentExtent;
VkExtent2D actualExtent = { (uint32)m_desiredExtent.x, (uint32)m_desiredExtent.y };
actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width));
actualExtent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actualExtent.height));
return actualExtent;
}
VkPresentModeKHR SwapchainInfoVk::ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes)
{
const auto vsyncState = (VSync)GetConfig().vsync.GetValue();
if (vsyncState == VSync::MAILBOX)
{
if (std::find(modes.cbegin(), modes.cend(), VK_PRESENT_MODE_MAILBOX_KHR) != modes.cend())
return VK_PRESENT_MODE_MAILBOX_KHR;
forceLog_printf("Vulkan: Can't find mailbox present mode");
}
else if (vsyncState == VSync::Immediate)
{
if (std::find(modes.cbegin(), modes.cend(), VK_PRESENT_MODE_IMMEDIATE_KHR) != modes.cend())
return VK_PRESENT_MODE_IMMEDIATE_KHR;
forceLog_printf("Vulkan: Can't find immediate present mode");
}
else if (vsyncState == VSync::SYNC_AND_LIMIT)
{
LatteTiming_EnableHostDrivenVSync();
// use immediate mode if available, other wise fall back to
//if (std::find(modes.cbegin(), modes.cend(), VK_PRESENT_MODE_IMMEDIATE_KHR) != modes.cend())
// return VK_PRESENT_MODE_IMMEDIATE_KHR;
//else
// forceLog_printf("Vulkan: Present mode 'immediate' not available. Vsync might not behave as intended");
return VK_PRESENT_MODE_FIFO_KHR;
}
return VK_PRESENT_MODE_FIFO_KHR;
}
VkSwapchainCreateInfoKHR SwapchainInfoVk::CreateSwapchainCreateInfo(VkSurfaceKHR surface, const SwapchainSupportDetails& swapchainSupport, const VkSurfaceFormatKHR& surfaceFormat, uint32 imageCount, const VkExtent2D& extent)
{
VkSwapchainCreateInfoKHR createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
createInfo.surface = surface;
createInfo.minImageCount = imageCount;
createInfo.imageFormat = surfaceFormat.format;
createInfo.imageExtent = extent;
createInfo.imageArrayLayers = 1;
createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
const QueueFamilyIndices indices = FindQueueFamilies(surface, m_physicalDevice);
uint32_t queueFamilyIndices[] = { (uint32)indices.graphicsFamily, (uint32)indices.presentFamily };
if (indices.graphicsFamily != indices.presentFamily)
{
createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
createInfo.queueFamilyIndexCount = 2;
createInfo.pQueueFamilyIndices = queueFamilyIndices;
}
else
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.preTransform = swapchainSupport.capabilities.currentTransform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
createInfo.presentMode = ChoosePresentMode(swapchainSupport.presentModes);
createInfo.clipped = VK_TRUE;
forceLogDebug_printf("vulkan presentation mode: %d", createInfo.presentMode);
return createInfo;
}
@@ -0,0 +1,93 @@
#pragma once
#include "util/math/vector2.h"
#include <vulkan/vulkan_core.h>
struct SwapchainInfoVk
{
enum class VSync
{
// values here must match GeneralSettings2::m_vsync
Immediate = 0,
FIFO = 1,
MAILBOX = 2,
SYNC_AND_LIMIT = 3, // synchronize emulated vsync events to monitor vsync. But skip events if rate higher than virtual vsync period
};
struct QueueFamilyIndices
{
int32_t graphicsFamily = -1;
int32_t presentFamily = -1;
bool IsComplete() const { return graphicsFamily >= 0 && presentFamily >= 0; }
};
struct SwapchainSupportDetails
{
VkSurfaceCapabilitiesKHR capabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentModes;
};
void Cleanup();
void Create(VkPhysicalDevice physicalDevice, VkDevice logicalDevice);
bool IsValid() const;
static void UnrecoverableError(const char* errMsg);
// todo: move this function somewhere more sensible. Not directly swapchain related
static QueueFamilyIndices FindQueueFamilies(VkSurfaceKHR surface, VkPhysicalDevice device);
static SwapchainSupportDetails QuerySwapchainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device);
VkPresentModeKHR ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes);
VkSurfaceFormatKHR ChooseSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& formats) const;
VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) const;
VkSwapchainCreateInfoKHR CreateSwapchainCreateInfo(VkSurfaceKHR surface, const SwapchainSupportDetails& swapchainSupport, const VkSurfaceFormatKHR& surfaceFormat, uint32 imageCount, const VkExtent2D& extent);
VkExtent2D getExtent() const
{
return m_actualExtent;
}
SwapchainInfoVk(VkSurfaceKHR surface, bool mainWindow)
: surface(surface), mainWindow(mainWindow) {}
SwapchainInfoVk(const SwapchainInfoVk&) = delete;
SwapchainInfoVk(SwapchainInfoVk&&) noexcept = default;
~SwapchainInfoVk()
{
Cleanup();
}
bool mainWindow{};
bool m_shouldRecreate = false;
bool m_usesSRGB = false;
VSync m_vsyncState = VSync::Immediate;
bool hasDefinedSwapchainImage{}; // indicates if the swapchain image is in a defined state
VkPhysicalDevice m_physicalDevice{};
VkDevice m_logicalDevice{};
VkSurfaceKHR surface{};
VkSurfaceFormatKHR m_surfaceFormat{};
VkSwapchainKHR swapchain{};
Vector2i m_desiredExtent{};
VkFence m_imageAvailableFence{};
uint32 swapchainImageIndex = (uint32)-1;
uint32 m_acquireIndex = 0; // increases with every successful vkAcquireNextImageKHR
// swapchain image ringbuffer (indexed by swapchainImageIndex)
std::vector<VkImage> m_swapchainImages;
std::vector<VkImageView> m_swapchainImageViews;
std::vector<VkFramebuffer> m_swapchainFramebuffers;
std::vector<VkSemaphore> m_swapchainPresentSemaphores;
std::vector<VkSemaphore> m_acquireSemaphores; // indexed by acquireIndex
VkRenderPass m_swapchainRenderPass = nullptr;
private:
VkExtent2D m_actualExtent{};
};
@@ -457,6 +457,12 @@ void PipelineCompiler::InitVertexInputState(const LatteContextRegister& latteReg
uint32 bufferStride = (latteRegister.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF;
VkVertexInputBindingDescription entry{};
#if BOOST_OS_MACOS
if (bufferStride % 4 != 0) {
forceLog_printf("MoltenVK error: vertex stride was %d, expected multiple of 4", bufferStride);
bufferStride = 0;
}
#endif
entry.stride = bufferStride;
if (!fetchType.has_value() || fetchType == LatteConst::VertexFetchType2::VERTEX_DATA)
entry.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More