19 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
39 changed files with 1287 additions and 771 deletions
+36 -12
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 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:
@@ -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/
+17 -6
View File
@@ -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
+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,20 +362,6 @@ void OpenGLRenderer::NotifyLatteCommandProcessorIdle()
glFlush();
}
void OpenGLRenderer::UpdateVSyncState()
{
int configValue = GetConfig().vsync.GetValue();
if(m_activeVSyncState != configValue)
{
#if BOOST_OS_WINDOWS
if(wglSwapIntervalEXT)
wglSwapIntervalEXT(configValue); // 1 = enabled, 0 = disabled
#else
cemuLog_log(LogType::Force, "OpenGL vsync not implemented");
#endif
m_activeVSyncState = configValue;
}
}
bool IsRunningInWine();
@@ -443,7 +439,6 @@ void OpenGLRenderer::EnableDebugMode()
void OpenGLRenderer::SwapBuffers(bool swapTV, bool swapDRC)
{
GLCanvas_SwapBuffers(swapTV, swapDRC);
UpdateVSyncState();
if (swapTV)
cleanupAfterFrame();
@@ -168,7 +168,6 @@ private:
GLuint m_defaultFramebufferId;
GLuint m_pipeline = 0;
int m_activeVSyncState{};
bool m_isPadViewContext{};
// rendertarget viewport
@@ -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{};
};
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,5 @@
#pragma once
#include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/RendererShaderVk.h"
@@ -6,6 +7,7 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/LatteTextureViewVk.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/CachedFBOVk.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/VKRMemoryManager.h"
#include "Cafe/HW/Latte/Renderer/Vulkan/SwapchainInfoVk.h"
#include "util/math/vector2.h"
#include "util/helpers/Semaphore.h"
#include "util/containers/flat_hash_map.hpp"
@@ -124,6 +126,9 @@ class VulkanRenderer : public Renderer
friend class LatteTextureReadbackInfoVk;
friend class PipelineCompiler;
using VSync = SwapchainInfoVk::VSync;
using QueueFamilyIndices = SwapchainInfoVk::QueueFamilyIndices;
static const inline int UNIFORMVAR_RINGBUFFER_SIZE = 1024 * 1024 * 16; // 16MB
static const inline int INDEX_STREAM_BUFFER_SIZE = 16 * 1024 * 1024; // 16 MB
@@ -132,15 +137,7 @@ class VulkanRenderer : public Renderer
static const inline int OCCLUSION_QUERY_POOL_SIZE = 1024;
public:
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
};
// memory management
VKRMemoryManager* memoryManager{};
VKRMemoryManager* GetMemoryManager() const { return memoryManager; };
@@ -185,12 +182,15 @@ public:
void GetDeviceFeatures();
void DetermineVendor();
void Initialize(const Vector2i& size, bool isMainWindow);
void Initialize(const Vector2i& size, bool mainWindow);
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
void StopUsingPadAndWait();
bool IsPadWindowActive() override;
void HandleScreenshotRequest(LatteTextureView* texView, bool padView) override;
void ResizeSwapchain(const Vector2i& size, bool isMainWindow);
void QueryMemoryInfo();
void QueryAvailableFormats();
@@ -210,7 +210,7 @@ public:
void ImguiInit();
VkInstance GetVkInstance() const { return m_instance; }
VkDevice GetLogicalDevice() const { return m_logicalDevice; }
VkPhysicalDevice GetPhysicalDevice() const { return m_physical_device; }
VkPhysicalDevice GetPhysicalDevice() const { return m_physicalDevice; }
VkDescriptorPool GetDescriptorPool() const { return m_descriptorPool; }
@@ -431,86 +431,14 @@ private:
bool drawSequenceSkip; // if true, skip draw_execute()
}m_state;
// swapchain - todo move this to m_swapchainState
struct SwapChainInfo
{
SwapChainInfo(VkDevice device, VkSurfaceKHR surface) : m_device(device), surface(surface) {}
SwapChainInfo(const SwapChainInfo&) = delete;
SwapChainInfo(SwapChainInfo&&) noexcept = default;
~SwapChainInfo()
{
if (m_swapChainRenderPass)
{
vkDestroyRenderPass(m_device, m_swapChainRenderPass, nullptr);
m_swapChainRenderPass = VK_NULL_HANDLE;
}
if (swapChain)
{
vkDestroySwapchainKHR(m_device, swapChain, nullptr);
swapChain = VK_NULL_HANDLE;
}
for (auto& imageView : m_swapchainImageViews)
vkDestroyImageView(m_device, imageView, nullptr);
m_swapchainImageViews.clear();
for (auto& framebuffer : m_swapchainFramebuffers)
vkDestroyFramebuffer(m_device, framebuffer, nullptr);
m_swapchainFramebuffers.clear();
}
VkDevice m_device;
VkSurfaceKHR surface{};
VkSwapchainKHR swapChain{};
VkExtent2D swapchainExtend{};
uint32 swapchainImageIndex = (uint32)-1;
uint32 m_acquireIndex = 0; // increases with every successful vkAcquireNextImageKHR
VSync m_activeVSyncState = VSync::Immediate;
struct AcquireInfo
{
// move fence here?
VkSemaphore acquireSemaphore;
};
std::vector<AcquireInfo> m_acquireInfo; // indexed by acquireIndex
// 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;
VkFence m_imageAvailableFence = nullptr;
VkRenderPass m_swapChainRenderPass = nullptr;
VkRenderPass m_imguiRenderPass = nullptr;
};
std::unique_ptr<SwapChainInfo> m_mainSwapchainInfo{}, m_padSwapchainInfo{};
std::unique_ptr<SwapchainInfoVk> m_mainSwapchainInfo{}, m_padSwapchainInfo{};
Semaphore m_padCloseReadySemaphore;
bool m_destroyPadSwapchainNextAcquire = false;
bool IsSwapchainInfoValid(bool mainWindow) const;
VkSwapchainKHR CreateSwapChain(SwapChainInfo& swap_chain_info, const Vector2i& size, bool mainwindow);
struct
{
bool resizeRequestedMainWindow{};
Vector2i newExtentMainWindow;
bool resizeRequestedPadWindow{};
Vector2i newExtentPadWindow;
bool tvHasDefinedSwapchainImage{}; // indicates if the swapchain image is in a defined state
bool drcHasDefinedSwapchainImage{};
}m_swapchainState;
VkRenderPass m_imguiRenderPass = nullptr;
VkDescriptorPool m_descriptorPool;
VkSurfaceFormatKHR m_swapchainFormat;
bool m_tvBufferUsesSRGB = false;
bool m_drvBufferUsesSRGB = false;
struct QueueFamilyIndices
{
int32_t graphicsFamily = -1;
int32_t presentFamily = -1;
bool IsComplete() const { return graphicsFamily >= 0 && presentFamily >= 0; }
};
static QueueFamilyIndices FindQueueFamilies(VkSurfaceKHR surface, const VkPhysicalDevice& device);
struct FeatureControl
{
@@ -556,15 +484,8 @@ private:
static bool CheckDeviceExtensionSupport(const VkPhysicalDevice device, FeatureControl& info);
static std::vector<const char*> CheckInstanceExtensionSupport(FeatureControl& info);
void UpdateVSyncState(bool main_window);
void SwapBuffer(bool main_window);
struct SwapChainSupportDetails
{
VkSurfaceCapabilitiesKHR capabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentModes;
};
bool UpdateSwapchainProperties(bool mainWindow);
void SwapBuffer(bool mainWindow);
VkDescriptorSetLayout m_swapchainDescriptorSetLayout;
@@ -572,14 +493,9 @@ private:
// swapchain
static SwapChainSupportDetails QuerySwapChainSupport(VkSurfaceKHR surface, const VkPhysicalDevice& device);
std::vector<VkDeviceQueueCreateInfo> CreateQueueCreateInfos(const std::set<int>& uniqueQueueFamilies) const;
VkDeviceCreateInfo CreateDeviceCreateInfo(const std::vector<VkDeviceQueueCreateInfo>& queueCreateInfos, const VkPhysicalDeviceFeatures& deviceFeatures, const void* deviceExtensionStructs, std::vector<const char*>& used_extensions) const;
static bool IsDeviceSuitable(VkSurfaceKHR surface, const VkPhysicalDevice& device);
VkSurfaceFormatKHR ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& formats, bool mainWindow) const;
VkPresentModeKHR ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& modes);
VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, const Vector2i& size) const;
VkSwapchainCreateInfoKHR CreateSwapchainCreateInfo(VkSurfaceKHR surface, const SwapChainSupportDetails& swapChainSupport, const VkSurfaceFormatKHR& surfaceFormat, uint32 imageCount, const VkExtent2D& extent);
void CreateCommandPool();
void CreateCommandBuffers();
@@ -641,8 +557,8 @@ private:
void CreatePipelineCache();
VkPipelineShaderStageCreateInfo CreatePipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule& module, const char* entryName) const;
VkPipeline backbufferBlit_createGraphicsPipeline(VkDescriptorSetLayout descriptorLayout, bool padView, RendererOutputShader* shader);
void AcquireNextSwapchainImage(bool main_window);
void RecreateSwapchain(bool mainwindow);
bool AcquireNextSwapchainImage(bool mainWindow);
void RecreateSwapchain(bool mainWindow, bool skipCreate = false);
// streamout
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;
@@ -665,7 +581,7 @@ private:
std::vector<const char*> m_layerNames;
VkInstance m_instance = VK_NULL_HANDLE;
VkPhysicalDevice m_physical_device = VK_NULL_HANDLE;
VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE;
VkDevice m_logicalDevice = VK_NULL_HANDLE;
VkDebugUtilsMessengerEXT m_debugCallback = nullptr;
volatile bool m_destructionRequested = false;
+1 -1
View File
@@ -273,7 +273,7 @@ void iosuCrypto_generateDeviceCertificate()
BIGNUM* bn_x = BN_CTX_get(context);
BIGNUM* bn_y = BN_CTX_get(context);
EC_POINT_get_affine_coordinates_GF2m(group, pubkey, bn_x, bn_y, NULL);
EC_POINT_get_affine_coordinates(group, pubkey, bn_x, bn_y, NULL);
uint8 publicKeyOutput[0x3C];
memset(publicKeyOutput, 0, sizeof(publicKeyOutput));
+1 -4
View File
@@ -346,7 +346,6 @@ namespace erreula
std::string button2 = "No";
if (appearArg.button2Text)
button2 = boost::nowide::narrow(GetText(appearArg.button2Text.GetPtr()));
float width1 = std::max(100.0f, ImGui::CalcTextSize(button1.c_str()).x + 10.0f);
float width2 = std::max(100.0f, ImGui::CalcTextSize(button2.c_str()).x + 10.0f);
@@ -359,10 +358,8 @@ namespace erreula
break;
}
}
ImGui::End();
}
ImGui::End();
ImGui::PopFont();
if(g_errEula.buttonPressed || g_errEula.rightButtonPressed)

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