Compare commits

..

No commits in common. "main" and "v.0.8.0" have entirely different histories.

48 changed files with 318 additions and 712 deletions

View file

@ -30,7 +30,7 @@ jobs:
- name: Install - name: Install
run: | run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main' sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main'
sudo apt update sudo apt update
sudo apt install clang-format-19 sudo apt install clang-format-19
- name: Build - name: Build
@ -281,13 +281,8 @@ jobs:
with: with:
submodules: recursive submodules: recursive
- name: Add LLVM repository
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
- name: Install dependencies - name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang-19 mold build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration - name: Cache CMake Configuration
uses: actions/cache@v4 uses: actions/cache@v4
@ -309,7 +304,7 @@ jobs:
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }} key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake - name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
@ -342,13 +337,8 @@ jobs:
with: with:
submodules: recursive submodules: recursive
- name: Add LLVM repository
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
- name: Install dependencies - name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang-19 mold build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration - name: Cache CMake Configuration
uses: actions/cache@v4 uses: actions/cache@v4
@ -370,7 +360,7 @@ jobs:
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }} key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake - name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
@ -395,7 +385,7 @@ jobs:
submodules: recursive submodules: recursive
- name: Install dependencies - name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 mold build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration - name: Cache CMake Configuration
uses: actions/cache@v4 uses: actions/cache@v4
@ -417,7 +407,7 @@ jobs:
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }} key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake - name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
@ -431,7 +421,7 @@ jobs:
submodules: recursive submodules: recursive
- name: Install dependencies - name: Install dependencies
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 mold build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
- name: Cache CMake Configuration - name: Cache CMake Configuration
uses: actions/cache@v4 uses: actions/cache@v4
@ -453,7 +443,7 @@ jobs:
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }} key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
- name: Configure CMake - name: Configure CMake
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
- name: Build - name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)

View file

@ -203,12 +203,12 @@ execute_process(
# Set Version # Set Version
set(EMULATOR_VERSION_MAJOR "0") set(EMULATOR_VERSION_MAJOR "0")
set(EMULATOR_VERSION_MINOR "8") set(EMULATOR_VERSION_MINOR "8")
set(EMULATOR_VERSION_PATCH "1") set(EMULATOR_VERSION_PATCH "0")
set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}") set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}")
set(APP_VERSION "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH} WIP") set(APP_VERSION "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH}")
set(APP_IS_RELEASE false) set(APP_IS_RELEASE true)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
message("end git things, remote: ${GIT_REMOTE_NAME}, branch: ${GIT_BRANCH}") message("end git things, remote: ${GIT_REMOTE_NAME}, branch: ${GIT_BRANCH}")
@ -840,7 +840,6 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
src/shader_recompiler/ir/passes/identity_removal_pass.cpp src/shader_recompiler/ir/passes/identity_removal_pass.cpp
src/shader_recompiler/ir/passes/ir_passes.h src/shader_recompiler/ir/passes/ir_passes.h
src/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp src/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp
src/shader_recompiler/ir/passes/lower_fp64_to_fp32.cpp
src/shader_recompiler/ir/passes/readlane_elimination_pass.cpp src/shader_recompiler/ir/passes/readlane_elimination_pass.cpp
src/shader_recompiler/ir/passes/resource_tracking_pass.cpp src/shader_recompiler/ir/passes/resource_tracking_pass.cpp
src/shader_recompiler/ir/passes/ring_access_elimination.cpp src/shader_recompiler/ir/passes/ring_access_elimination.cpp
@ -1085,31 +1084,33 @@ endif()
if (APPLE) if (APPLE)
# Include MoltenVK, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers. # Include MoltenVK, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers.
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
if (ENABLE_QT_GUI) if (ENABLE_QT_GUI)
set(MVK_BUNDLE_PATH "Resources/vulkan/icd.d") set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks")
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLE_PATH}") set(MVK_ICD_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json)
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/${MVK_BUNDLE_PATH}) set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib)
set(MVK_DYLIB_ICD_PATH "../../../Frameworks/libMoltenVK.dylib")
else() else()
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path") set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path")
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR}) set(MVK_ICD_DST ${CMAKE_CURRENT_BINARY_DIR}/MoltenVK_icd.json)
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/libMoltenVK.dylib)
set(MVK_DYLIB_ICD_PATH "./libMoltenVK.dylib")
endif() endif()
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib) cmake_path(GET MVK_ICD_DST PARENT_PATH MVK_ICD_DST_PARENT)
set(MVK_DYLIB_DST ${MVK_DST}/libMoltenVK.dylib) cmake_path(GET MVK_DYLIB_DST PARENT_PATH MVK_DYLIB_DST_PARENT)
set(MVK_ICD_SRC ${CMAKE_CURRENT_SOURCE_DIR}/externals/MoltenVK/MoltenVK/MoltenVK/icd/MoltenVK_icd.json)
set(MVK_ICD_DST ${MVK_DST}/MoltenVK_icd.json)
add_custom_command( set(MVK_ICD "\\\{ \\\"file_format_version\\\": \\\"1.0.0\\\", \\\"ICD\\\": \\\{ \\\"library_path\\\": \\\"${MVK_DYLIB_ICD_PATH}\\\", \\\"api_version\\\": \\\"1.2.0\\\", \\\"is_portability_driver\\\": true \\\} \\\}")
OUTPUT ${MVK_DST}
COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DST})
add_custom_command( add_custom_command(
OUTPUT ${MVK_ICD_DST} OUTPUT ${MVK_ICD_DST}
DEPENDS ${MVK_ICD_SRC} ${MVK_DST} COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_ICD_DST_PARENT} && ${CMAKE_COMMAND} -E echo ${MVK_ICD} > ${MVK_ICD_DST})
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_ICD_SRC} ${MVK_ICD_DST})
add_custom_command( add_custom_command(
OUTPUT ${MVK_DYLIB_DST} OUTPUT ${MVK_DYLIB_DST}
DEPENDS ${MVK_DYLIB_SRC} ${MVK_DST} DEPENDS ${MVK_DYLIB_SRC}
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST}) COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DYLIB_DST_PARENT} && ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST}) add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST})
add_dependencies(CopyMoltenVK MoltenVK) add_dependencies(CopyMoltenVK MoltenVK)
add_dependencies(shadps4 CopyMoltenVK) add_dependencies(shadps4 CopyMoltenVK)

@ -1 +1 @@
Subproject commit 87a8e8b13d4ad8835367fea1ebad1896d0460946 Subproject commit 4cf8f94684c53e581eb9cc694dd3305d1f7d9959

@ -1 +1 @@
Subproject commit 7918775748c5e2f5c40d9918ce68825035b5a1e1 Subproject commit 2275d0efc4f2fa46851035d9d3c67c105bc8b99e

View file

@ -169,8 +169,7 @@ void OnGameLoaded() {
if (type == "mask_jump32") if (type == "mask_jump32")
patchMask = MemoryPatcher::PatchMask::Mask_Jump32; patchMask = MemoryPatcher::PatchMask::Mask_Jump32;
if ((type == "mask" || type == "mask_jump32") && if (type == "mask" || type == "mask_jump32" && !maskOffsetStr.empty()) {
!maskOffsetStr.empty()) {
maskOffsetValue = std::stoi(maskOffsetStr, 0, 10); maskOffsetValue = std::stoi(maskOffsetStr, 0, 10);
} }

View file

@ -1,11 +1,11 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "SDL3/SDL_log.h"
#include "layer.h" #include "layer.h"
#include <imgui.h> #include <imgui.h>
#include "SDL3/SDL_log.h"
#include "common/config.h" #include "common/config.h"
#include "common/singleton.h" #include "common/singleton.h"
#include "common/types.h" #include "common/types.h"

View file

@ -1,14 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "options.h"
#include <memory>
#include <imgui.h> #include <imgui.h>
#include "video_core/renderer_vulkan/vk_presenter.h" #include "options.h"
extern std::unique_ptr<Vulkan::Presenter> presenter;
namespace Core::Devtools { namespace Core::Devtools {
@ -17,7 +12,6 @@ TOptions Options;
void LoadOptionsConfig(const char* line) { void LoadOptionsConfig(const char* line) {
char str[512]; char str[512];
int i; int i;
float f;
if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) { if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) {
Options.disassembler_cli_isa = str; Options.disassembler_cli_isa = str;
return; return;
@ -30,26 +24,12 @@ void LoadOptionsConfig(const char* line) {
Options.frame_dump_render_on_collapse = i != 0; Options.frame_dump_render_on_collapse = i != 0;
return; return;
} }
if (sscanf(line, "fsr_enabled=%d", &i) == 1) {
presenter->GetFsrSettingsRef().enable = i != 0;
return;
}
if (sscanf(line, "fsr_rcas_enabled=%d", &i) == 1) {
presenter->GetFsrSettingsRef().use_rcas = i != 0;
return;
}
if (sscanf(line, "fsr_rcas_attenuation=%f", &f) == 1) {
presenter->GetFsrSettingsRef().rcas_attenuation = f;
}
} }
void SerializeOptionsConfig(ImGuiTextBuffer* buf) { void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str()); buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str());
buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str()); buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str());
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse); buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
buf->appendf("fsr_enabled=%d\n", presenter->GetFsrSettingsRef().enable);
buf->appendf("fsr_rcas_enabled=%d\n", presenter->GetFsrSettingsRef().use_rcas);
buf->appendf("fsr_rcas_attenuation=%f\n", presenter->GetFsrSettingsRef().rcas_attenuation);
} }
} // namespace Core::Devtools } // namespace Core::Devtools

View file

@ -83,35 +83,9 @@ int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm() {
return ORBIS_OK; return ORBIS_OK;
} }
Error PS4_SYSV_ABI sceImeDialogGetPanelSize(const OrbisImeDialogParam* param, u32* width, int PS4_SYSV_ABI sceImeDialogGetPanelSize() {
u32* height) { LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
LOG_INFO(Lib_ImeDialog, "called"); return ORBIS_OK;
if (!width || !height) {
return Error::INVALID_ADDRESS;
}
switch (param->type) {
case OrbisImeType::Default:
case OrbisImeType::BasicLatin:
case OrbisImeType::Url:
case OrbisImeType::Mail:
*width = 500; // original: 793
if (True(param->option & OrbisImeDialogOption::Multiline)) {
*height = 300; // original: 576
} else {
*height = 150; // original: 476
}
break;
case OrbisImeType::Number:
*width = 370;
*height = 470;
break;
default:
LOG_ERROR(Lib_ImeDialog, "Unknown OrbisImeType: {}", (u32)param->type);
return Error::INVALID_PARAM;
}
return Error::OK;
} }
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() { int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() {

View file

@ -13,7 +13,7 @@ class SymbolsResolver;
namespace Libraries::ImeDialog { namespace Libraries::ImeDialog {
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048; constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 0x78;
enum class Error : u32 { enum class Error : u32 {
OK = 0x0, OK = 0x0,
@ -155,8 +155,7 @@ Error PS4_SYSV_ABI sceImeDialogForceClose();
Error PS4_SYSV_ABI sceImeDialogForTestFunction(); Error PS4_SYSV_ABI sceImeDialogForTestFunction();
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState(); int PS4_SYSV_ABI sceImeDialogGetCurrentStarState();
int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm(); int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm();
Error PS4_SYSV_ABI sceImeDialogGetPanelSize(const OrbisImeDialogParam* param, u32* width, int PS4_SYSV_ABI sceImeDialogGetPanelSize();
u32* height);
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended(); int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended();
Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result); Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result);
OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus(); OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus();

View file

@ -61,18 +61,6 @@ struct SceKernelEvent {
void* udata = nullptr; /* opaque user data identifier */ void* udata = nullptr; /* opaque user data identifier */
}; };
struct OrbisVideoOutEventHint {
u64 event_id : 8;
u64 video_id : 8;
u64 flip_arg : 48;
};
struct OrbisVideoOutEventData {
u64 time : 12;
u64 count : 4;
u64 flip_arg : 48;
};
struct EqueueEvent { struct EqueueEvent {
SceKernelEvent event; SceKernelEvent event;
void* data = nullptr; void* data = nullptr;
@ -96,18 +84,19 @@ struct EqueueEvent {
void TriggerDisplay(void* data) { void TriggerDisplay(void* data) {
is_triggered = true; is_triggered = true;
if (data != nullptr) { auto hint = reinterpret_cast<u64>(data);
auto event_data = static_cast<OrbisVideoOutEventData>(event.data); if (hint != 0) {
auto event_hint_raw = reinterpret_cast<u64>(data); auto hint_h = static_cast<u32>(hint >> 8) & 0xFFFFFF;
auto event_hint = static_cast<OrbisVideoOutEventHint>(event_hint_raw); auto ident_h = static_cast<u32>(event.ident >> 40);
if (event_hint.event_id == event.ident && event.ident != 0xfe) { if ((static_cast<u32>(hint) & 0xFF) == event.ident && event.ident != 0xFE &&
((hint_h ^ ident_h) & 0xFF) == 0) {
auto time = Common::FencedRDTSC(); auto time = Common::FencedRDTSC();
auto counter = event_data.count; auto mask = 0xF000;
if (counter != 0xf) { if ((static_cast<u32>(event.data) & 0xF000) != 0xF000) {
counter++; mask = (static_cast<u32>(event.data) + 0x1000) & 0xF000;
} }
event.data = event.data = (mask | static_cast<u64>(static_cast<u32>(time) & 0xFFF) |
(time & 0xfff) | (counter << 0xc) | (event_hint_raw & 0xffffffffffff0000); (hint & 0xFFFFFFFFFFFF0000));
} }
} }
} }

View file

@ -127,62 +127,6 @@ int PS4_SYSV_ABI sceKernelGetModuleInfoFromAddr(VAddr addr, int flags,
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceKernelGetModuleInfo(s32 handle, Core::OrbisKernelModuleInfo* info) {
if (info == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (info->st_size != sizeof(Core::OrbisKernelModuleInfo)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
auto* module = linker->GetModule(handle);
if (module == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
*info = module->GetModuleInfo();
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelGetModuleInfoInternal(s32 handle, Core::OrbisKernelModuleInfoEx* info) {
if (info == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
if (info->st_size != sizeof(Core::OrbisKernelModuleInfoEx)) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
auto* module = linker->GetModule(handle);
if (module == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
*info = module->GetModuleInfoEx();
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceKernelGetModuleList(s32* handles, u64 num_array, u64* out_count) {
if (handles == nullptr || out_count == nullptr) {
return ORBIS_KERNEL_ERROR_EFAULT;
}
auto* linker = Common::Singleton<Core::Linker>::Instance();
u64 count = 0;
auto* module = linker->GetModule(count);
while (module != nullptr && count < num_array) {
handles[count] = count;
count++;
module = linker->GetModule(count);
}
if (count == num_array && module != nullptr) {
return ORBIS_KERNEL_ERROR_ENOMEM;
}
*out_count = count;
return ORBIS_OK;
}
s32 PS4_SYSV_ABI exit(s32 status) { s32 PS4_SYSV_ABI exit(s32 status) {
UNREACHABLE_MSG("Exiting with status code {}", status); UNREACHABLE_MSG("Exiting with status code {}", status);
return 0; return 0;
@ -197,9 +141,6 @@ void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym); LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind); LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind);
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr); LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr);
LIB_FUNCTION("kUpgrXIrz7Q", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfo);
LIB_FUNCTION("HZO7xOos4xc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoInternal);
LIB_FUNCTION("IuxnUuXk6Bg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleList);
LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, exit); LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, exit);
} }

View file

@ -19,40 +19,11 @@ int PS4_SYSV_ABI sceSysmoduleGetModuleHandleInternal() {
return ORBIS_OK; return ORBIS_OK;
} }
s32 PS4_SYSV_ABI sceSysmoduleGetModuleInfoForUnwind(VAddr addr, s32 flags, s32 PS4_SYSV_ABI sceSysmoduleGetModuleInfoForUnwind(VAddr addr, s32 flags, void* info) {
Kernel::OrbisModuleInfoForUnwind* info) { LOG_ERROR(Lib_SysModule, "(STUBBED) called");
LOG_TRACE(Lib_SysModule, "sceSysmoduleGetModuleInfoForUnwind(addr=0x{:X}, flags=0x{:X})", addr, Kernel::OrbisModuleInfoForUnwind module_info;
flags); module_info.st_size = 0x130;
s32 res = Kernel::sceKernelGetModuleInfoForUnwind(addr, flags, &module_info);
s32 res = Kernel::sceKernelGetModuleInfoForUnwind(addr, flags, info);
if (res != 0) {
return res;
}
static constexpr std::array<std::string_view, 17> modules_to_hide = {
"libc.prx",
"libc.sprx",
"libSceAudioLatencyEstimation.prx",
"libSceFace.prx",
"libSceFaceTracker.prx",
"libSceFios2.prx",
"libSceFios2.sprx",
"libSceFontGsm.prx",
"libSceHand.prx",
"libSceHandTracker.prx",
"libSceHeadTracker.prx",
"libSceJobManager.prx",
"libSceNpCppWebApi.prx",
"libSceNpToolkit.prx",
"libSceNpToolkit2.prx",
"libSceS3DConversion.prx",
"libSceSmart.prx",
};
const std::string_view module_name = info->name.data();
if (std::ranges::find(modules_to_hide, module_name) != modules_to_hide.end()) {
std::ranges::fill(info->name, '\0');
}
return res; return res;
} }
@ -85,6 +56,7 @@ int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(OrbisSysModuleInternal id) {
} }
int PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id) { int PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id) {
auto color_name = magic_enum::enum_name(id);
LOG_ERROR(Lib_SysModule, "(DUMMY) called module = {}", magic_enum::enum_name(id)); LOG_ERROR(Lib_SysModule, "(DUMMY) called module = {}", magic_enum::enum_name(id));
return ORBIS_OK; return ORBIS_OK;
} }

View file

@ -4,7 +4,6 @@
#pragma once #pragma once
#include "common/types.h" #include "common/types.h"
#include "core/libraries/kernel/process.h"
namespace Core::Loader { namespace Core::Loader {
class SymbolsResolver; class SymbolsResolver;
@ -153,8 +152,7 @@ enum class OrbisSysModuleInternal : u32 {
}; };
int PS4_SYSV_ABI sceSysmoduleGetModuleHandleInternal(); int PS4_SYSV_ABI sceSysmoduleGetModuleHandleInternal();
s32 PS4_SYSV_ABI sceSysmoduleGetModuleInfoForUnwind(VAddr addr, s32 flags, s32 PS4_SYSV_ABI sceSysmoduleGetModuleInfoForUnwind(VAddr addr, s32 flags, void* info);
Kernel::OrbisModuleInfoForUnwind* info);
int PS4_SYSV_ABI sceSysmoduleIsCalledFromSysModule(); int PS4_SYSV_ABI sceSysmoduleIsCalledFromSysModule();
int PS4_SYSV_ABI sceSysmoduleIsCameraPreloaded(); int PS4_SYSV_ABI sceSysmoduleIsCameraPreloaded();
int PS4_SYSV_ABI sceSysmoduleIsLoaded(OrbisSysModule id); int PS4_SYSV_ABI sceSysmoduleIsLoaded(OrbisSysModule id);

View file

@ -220,7 +220,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64*
if (ev->ident != static_cast<s32>(OrbisVideoOutInternalEventId::Flip) || ev->data == 0) { if (ev->ident != static_cast<s32>(OrbisVideoOutInternalEventId::Flip) || ev->data == 0) {
*data = event_data; *data = event_data;
} else { } else {
*data = event_data | 0xffff000000000000; *data = event_data | 0xFFFF000000000000;
} }
return ORBIS_OK; return ORBIS_OK;
} }
@ -233,8 +233,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetEventCount(const Kernel::SceKernelEvent* ev) {
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT; return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT;
} }
auto event_data = static_cast<OrbisVideoOutEventData>(ev->data); return (ev->data >> 0xc) & 0xf;
return event_data.count;
} }
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) { s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) {

View file

@ -111,12 +111,6 @@ struct SceVideoOutColorSettings {
u32 reserved[3]; u32 reserved[3];
}; };
struct OrbisVideoOutEventData {
u64 time : 12;
u64 count : 4;
u64 flip_arg : 48;
};
void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat, void PS4_SYSV_ABI sceVideoOutSetBufferAttribute(BufferAttribute* attribute, PixelFormat pixelFormat,
u32 tilingMode, u32 aspectRatio, u32 width, u32 tilingMode, u32 aspectRatio, u32 width,
u32 height, u32 pitchInPixel); u32 height, u32 pitchInPixel);
@ -134,8 +128,8 @@ s32 PS4_SYSV_ABI sceVideoOutGetResolutionStatus(s32 handle, SceVideoOutResolutio
s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index, s32 PS4_SYSV_ABI sceVideoOutOpen(SceUserServiceUserId userId, s32 busType, s32 index,
const void* param); const void* param);
s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle); s32 PS4_SYSV_ABI sceVideoOutClose(s32 handle);
s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev); int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev);
s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64* data); int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data);
s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma); s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* settings, float gamma);
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings); s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings);

View file

@ -83,7 +83,7 @@ public:
} }
Module* GetModule(s32 index) const { Module* GetModule(s32 index) const {
if (index >= 0 && index < m_modules.size()) { if (index >= 0 || index < m_modules.size()) {
return m_modules.at(index).get(); return m_modules.at(index).get();
} }
return nullptr; return nullptr;

View file

@ -142,7 +142,7 @@ PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size,
auto mapping_start = search_start > dmem_area->second.base auto mapping_start = search_start > dmem_area->second.base
? Common::AlignUp(search_start, alignment) ? Common::AlignUp(search_start, alignment)
: Common::AlignUp(dmem_area->second.base, alignment); : Common::AlignUp(dmem_area->second.base, alignment);
auto mapping_end = mapping_start + size; auto mapping_end = Common::AlignUp(mapping_start + size, alignment);
// Find the first free, large enough dmem area in the range. // Find the first free, large enough dmem area in the range.
while ((!dmem_area->second.is_free || dmem_area->second.GetEnd() < mapping_end) && while ((!dmem_area->second.is_free || dmem_area->second.GetEnd() < mapping_end) &&
@ -151,8 +151,10 @@ PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size,
dmem_area++; dmem_area++;
// Update local variables based on the new dmem_area // Update local variables based on the new dmem_area
mapping_start = Common::AlignUp(dmem_area->second.base, alignment); mapping_start = search_start > dmem_area->second.base
mapping_end = mapping_start + size; ? Common::AlignUp(search_start, alignment)
: Common::AlignUp(dmem_area->second.base, alignment);
mapping_end = Common::AlignUp(mapping_start + size, alignment);
} }
if (dmem_area == dmem_map.end()) { if (dmem_area == dmem_map.end()) {

View file

@ -135,14 +135,10 @@ void Module::LoadModuleToMemory(u32& max_tls_index) {
if (do_map) { if (do_map) {
elf.LoadSegment(segment_addr, phdr.p_offset, phdr.p_filesz); elf.LoadSegment(segment_addr, phdr.p_offset, phdr.p_filesz);
} }
if (info.num_segments < 4) {
auto& segment = info.segments[info.num_segments++]; auto& segment = info.segments[info.num_segments++];
segment.address = segment_addr; segment.address = segment_addr;
segment.prot = phdr.p_flags; segment.prot = phdr.p_flags;
segment.size = GetAlignedSize(phdr); segment.size = GetAlignedSize(phdr);
} else {
LOG_ERROR(Core_Linker, "Attempting to add too many segments!");
}
}; };
for (u16 i = 0; i < elf_header.e_phnum; i++) { for (u16 i = 0; i < elf_header.e_phnum; i++) {

View file

@ -4,11 +4,8 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
#include <vector>
#include <imgui.h> #include <imgui.h>
#include "common/types.h"
namespace ImGui { namespace ImGui {
namespace Core::TextureManager { namespace Core::TextureManager {

View file

@ -112,8 +112,6 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w
if (const auto dpi = SDL_GetWindowDisplayScale(window.GetSDLWindow()); dpi > 0.0f) { if (const auto dpi = SDL_GetWindowDisplayScale(window.GetSDLWindow()); dpi > 0.0f) {
GetIO().FontGlobalScale = dpi; GetIO().FontGlobalScale = dpi;
} }
std::at_quick_exit([] { SaveIniSettingsToDisk(GetIO().IniFilename); });
} }
void OnResize() { void OnResize() {

View file

@ -154,7 +154,7 @@ int main(int argc, char* argv[]) {
// If no game directory is set and no command line argument, prompt for it // If no game directory is set and no command line argument, prompt for it
if (Config::getGameInstallDirs().empty()) { if (Config::getGameInstallDirs().empty()) {
std::cout << "Warning: No game folder set, please set it by calling shadps4" std::cout << "Warning: No game folder set, please set it by calling shadps4"
" with the --add-game-folder <folder_name> argument\n"; " with the --add-game-folder <folder_name> argument";
} }
if (!has_game_argument) { if (!has_game_argument) {

View file

@ -1387,7 +1387,7 @@ void CheatsPatches::applyPatch(const QString& patchName, bool enabled) {
if (type == "mask_jump32") if (type == "mask_jump32")
patchMask = MemoryPatcher::PatchMask::Mask_Jump32; patchMask = MemoryPatcher::PatchMask::Mask_Jump32;
if ((type == "mask" || type == "mask_jump32") && !maskOffsetStr.toStdString().empty()) { if (type == "mask" || type == "mask_jump32" && !maskOffsetStr.toStdString().empty()) {
maskOffsetValue = std::stoi(maskOffsetStr.toStdString(), 0, 10); maskOffsetValue = std::stoi(maskOffsetStr.toStdString(), 0, 10);
} }

View file

@ -608,29 +608,22 @@ void KBMSettings::CheckMapping(QPushButton*& button) {
MappingTimer -= 1; MappingTimer -= 1;
button->setText(tr("Press a key") + " [" + QString::number(MappingTimer) + "]"); button->setText(tr("Press a key") + " [" + QString::number(MappingTimer) + "]");
if (pressedKeys.size() > 0) {
QStringList keyStrings;
for (const QString& buttonAction : pressedKeys) {
keyStrings << buttonAction;
}
QString combo = keyStrings.join(",");
SetMapping(combo);
MappingCompleted = true;
EnableMapping = false;
MappingButton->setText(combo);
pressedKeys.clear();
timer->stop();
}
if (MappingCompleted) { if (MappingCompleted) {
EnableMapping = false; EnableMapping = false;
EnableMappingButtons(); EnableMappingButtons();
timer->stop(); timer->stop();
if (mapping == "lshift" || mapping == "lalt" || mapping == "lctrl" || mapping == "lmeta" ||
mapping == "lwin") {
modifier = "";
}
if (modifier != "") {
button->setText(modifier + ", " + mapping);
} else {
button->setText(mapping); button->setText(mapping);
} }
}
if (MappingTimer <= 0) { if (MappingTimer <= 0) {
button->setText(mapping); button->setText(mapping);
@ -654,328 +647,305 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
} }
if (EnableMapping) { if (EnableMapping) {
if (Qt::ShiftModifier & QApplication::keyboardModifiers()) {
modifier = "lshift";
} else if (Qt::AltModifier & QApplication::keyboardModifiers()) {
modifier = "lalt";
} else if (Qt::ControlModifier & QApplication::keyboardModifiers()) {
modifier = "lctrl";
} else if (Qt::MetaModifier & QApplication::keyboardModifiers()) {
#ifdef _WIN32
modifier = "lwin";
#else
modifier = "lmeta";
#endif
}
if (event->type() == QEvent::KeyPress) { if (event->type() == QEvent::KeyPress) {
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->isAutoRepeat())
return true;
if (pressedKeys.size() >= 3) {
return true;
}
switch (keyEvent->key()) { switch (keyEvent->key()) {
case Qt::Key_Space: case Qt::Key_Space:
pressedKeys.insert("space"); SetMapping("space");
break; break;
case Qt::Key_Comma: case Qt::Key_Comma:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kpcomma"); SetMapping("kpcomma");
} else { } else {
pressedKeys.insert("comma"); SetMapping("comma");
} }
break; break;
case Qt::Key_Period: case Qt::Key_Period:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kpperiod"); SetMapping("kpperiod");
} else { } else {
pressedKeys.insert("period"); SetMapping("period");
} }
break; break;
case Qt::Key_Slash: case Qt::Key_Slash:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) if (Qt::KeypadModifier & QApplication::keyboardModifiers())
pressedKeys.insert("kpdivide"); SetMapping("kpdivide");
break; break;
case Qt::Key_Asterisk: case Qt::Key_Asterisk:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) if (Qt::KeypadModifier & QApplication::keyboardModifiers())
pressedKeys.insert("kpmultiply"); SetMapping("kpmultiply");
break; break;
case Qt::Key_Question: case Qt::Key_Question:
pressedKeys.insert("question"); SetMapping("question");
break; break;
case Qt::Key_Semicolon: case Qt::Key_Semicolon:
pressedKeys.insert("semicolon"); SetMapping("semicolon");
break; break;
case Qt::Key_Minus: case Qt::Key_Minus:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kpminus"); SetMapping("kpminus");
} else { } else {
pressedKeys.insert("minus"); SetMapping("minus");
} }
break; break;
case Qt::Key_Plus: case Qt::Key_Plus:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kpplus"); SetMapping("kpplus");
} else { } else {
pressedKeys.insert("plus"); SetMapping("plus");
} }
break; break;
case Qt::Key_ParenLeft: case Qt::Key_ParenLeft:
pressedKeys.insert("lparenthesis"); SetMapping("lparenthesis");
break; break;
case Qt::Key_ParenRight: case Qt::Key_ParenRight:
pressedKeys.insert("rparenthesis"); SetMapping("rparenthesis");
break; break;
case Qt::Key_BracketLeft: case Qt::Key_BracketLeft:
pressedKeys.insert("lbracket"); SetMapping("lbracket");
break; break;
case Qt::Key_BracketRight: case Qt::Key_BracketRight:
pressedKeys.insert("rbracket"); SetMapping("rbracket");
break; break;
case Qt::Key_BraceLeft: case Qt::Key_BraceLeft:
pressedKeys.insert("lbrace"); SetMapping("lbrace");
break; break;
case Qt::Key_BraceRight: case Qt::Key_BraceRight:
pressedKeys.insert("rbrace"); SetMapping("rbrace");
break; break;
case Qt::Key_Backslash: case Qt::Key_Backslash:
pressedKeys.insert("backslash"); SetMapping("backslash");
break; break;
case Qt::Key_Tab: case Qt::Key_Tab:
pressedKeys.insert("tab"); SetMapping("tab");
break; break;
case Qt::Key_Backspace: case Qt::Key_Backspace:
pressedKeys.insert("backspace"); SetMapping("backspace");
break; break;
case Qt::Key_Return: case Qt::Key_Return:
pressedKeys.insert("enter"); SetMapping("enter");
break; break;
case Qt::Key_Enter: case Qt::Key_Enter:
pressedKeys.insert("kpenter"); SetMapping("kpenter");
break;
case Qt::Key_Home:
pressedKeys.insert("home");
break;
case Qt::Key_End:
pressedKeys.insert("end");
break;
case Qt::Key_PageDown:
pressedKeys.insert("pgdown");
break;
case Qt::Key_PageUp:
pressedKeys.insert("pgup");
break;
case Qt::Key_CapsLock:
pressedKeys.insert("capslock");
break; break;
case Qt::Key_Escape: case Qt::Key_Escape:
pressedKeys.insert("unmapped"); SetMapping("unmapped");
break; break;
case Qt::Key_Shift: case Qt::Key_Shift:
if (keyEvent->nativeScanCode() == rshift) { SetMapping("lshift");
pressedKeys.insert("rshift");
} else {
pressedKeys.insert("lshift");
}
break; break;
case Qt::Key_Alt: case Qt::Key_Alt:
if (keyEvent->nativeScanCode() == ralt) { SetMapping("lalt");
pressedKeys.insert("ralt");
} else {
pressedKeys.insert("lalt");
}
break; break;
case Qt::Key_Control: case Qt::Key_Control:
if (keyEvent->nativeScanCode() == rctrl) { SetMapping("lctrl");
pressedKeys.insert("rctrl");
} else {
pressedKeys.insert("lctrl");
}
break; break;
case Qt::Key_Meta: case Qt::Key_Meta:
activateWindow(); activateWindow();
#ifdef _WIN32 #ifdef _WIN32
pressedKeys.insert("lwin"); SetMapping("lwin");
#else #else
pressedKeys.insert("lmeta"); SetMapping("lmeta");
#endif #endif
case Qt::Key_1: case Qt::Key_1:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp1"); SetMapping("kp1");
} else { } else {
pressedKeys.insert("1"); SetMapping("1");
} }
break; break;
case Qt::Key_2: case Qt::Key_2:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp2"); SetMapping("kp2");
} else { } else {
pressedKeys.insert("2"); SetMapping("2");
} }
break; break;
case Qt::Key_3: case Qt::Key_3:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp3"); SetMapping("kp3");
} else { } else {
pressedKeys.insert("3"); SetMapping("3");
} }
break; break;
case Qt::Key_4: case Qt::Key_4:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp4"); SetMapping("kp4");
} else { } else {
pressedKeys.insert("4"); SetMapping("4");
} }
break; break;
case Qt::Key_5: case Qt::Key_5:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp5"); SetMapping("kp5");
} else { } else {
pressedKeys.insert("5"); SetMapping("5");
} }
break; break;
case Qt::Key_6: case Qt::Key_6:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp6"); SetMapping("kp6");
} else { } else {
pressedKeys.insert("6"); SetMapping("6");
} }
break; break;
case Qt::Key_7: case Qt::Key_7:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp7"); SetMapping("kp7");
} else { } else {
pressedKeys.insert("7"); SetMapping("7");
} }
break; break;
case Qt::Key_8: case Qt::Key_8:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp8"); SetMapping("kp8");
} else { } else {
pressedKeys.insert("8"); SetMapping("8");
} }
break; break;
case Qt::Key_9: case Qt::Key_9:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp9"); SetMapping("kp9");
} else { } else {
pressedKeys.insert("9"); SetMapping("9");
} }
break; break;
case Qt::Key_0: case Qt::Key_0:
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("kp0"); SetMapping("kp0");
} else { } else {
pressedKeys.insert("0"); SetMapping("0");
} }
break; break;
case Qt::Key_Up: case Qt::Key_Up:
activateWindow(); activateWindow();
pressedKeys.insert("up"); SetMapping("up");
break; break;
case Qt::Key_Down: case Qt::Key_Down:
pressedKeys.insert("down"); SetMapping("down");
break; break;
case Qt::Key_Left: case Qt::Key_Left:
pressedKeys.insert("left"); SetMapping("left");
break; break;
case Qt::Key_Right: case Qt::Key_Right:
pressedKeys.insert("right"); SetMapping("right");
break; break;
case Qt::Key_A: case Qt::Key_A:
pressedKeys.insert("a"); SetMapping("a");
break; break;
case Qt::Key_B: case Qt::Key_B:
pressedKeys.insert("b"); SetMapping("b");
break; break;
case Qt::Key_C: case Qt::Key_C:
pressedKeys.insert("c"); SetMapping("c");
break; break;
case Qt::Key_D: case Qt::Key_D:
pressedKeys.insert("d"); SetMapping("d");
break; break;
case Qt::Key_E: case Qt::Key_E:
pressedKeys.insert("e"); SetMapping("e");
break; break;
case Qt::Key_F: case Qt::Key_F:
pressedKeys.insert("f"); SetMapping("f");
break; break;
case Qt::Key_G: case Qt::Key_G:
pressedKeys.insert("g"); SetMapping("g");
break; break;
case Qt::Key_H: case Qt::Key_H:
pressedKeys.insert("h"); SetMapping("h");
break; break;
case Qt::Key_I: case Qt::Key_I:
pressedKeys.insert("i"); SetMapping("i");
break; break;
case Qt::Key_J: case Qt::Key_J:
pressedKeys.insert("j"); SetMapping("j");
break; break;
case Qt::Key_K: case Qt::Key_K:
pressedKeys.insert("k"); SetMapping("k");
break; break;
case Qt::Key_L: case Qt::Key_L:
pressedKeys.insert("l"); SetMapping("l");
break; break;
case Qt::Key_M: case Qt::Key_M:
pressedKeys.insert("m"); SetMapping("m");
break; break;
case Qt::Key_N: case Qt::Key_N:
pressedKeys.insert("n"); SetMapping("n");
break; break;
case Qt::Key_O: case Qt::Key_O:
pressedKeys.insert("o"); SetMapping("o");
break; break;
case Qt::Key_P: case Qt::Key_P:
pressedKeys.insert("p"); SetMapping("p");
break; break;
case Qt::Key_Q: case Qt::Key_Q:
pressedKeys.insert("q"); SetMapping("q");
break; break;
case Qt::Key_R: case Qt::Key_R:
pressedKeys.insert("r"); SetMapping("r");
break; break;
case Qt::Key_S: case Qt::Key_S:
pressedKeys.insert("s"); SetMapping("s");
break; break;
case Qt::Key_T: case Qt::Key_T:
pressedKeys.insert("t"); SetMapping("t");
break; break;
case Qt::Key_U: case Qt::Key_U:
pressedKeys.insert("u"); SetMapping("u");
break; break;
case Qt::Key_V: case Qt::Key_V:
pressedKeys.insert("v"); SetMapping("v");
break; break;
case Qt::Key_W: case Qt::Key_W:
pressedKeys.insert("w"); SetMapping("w");
break; break;
case Qt::Key_X: case Qt::Key_X:
pressedKeys.insert("x"); SetMapping("x");
break; break;
case Qt::Key_Y: case Qt::Key_Y:
pressedKeys.insert("Y"); SetMapping("Y");
break; break;
case Qt::Key_Z: case Qt::Key_Z:
pressedKeys.insert("z"); SetMapping("z");
break; break;
default: default:
break; break;
} }
return true; return true;
} }
}
if (event->type() == QEvent::MouseButtonPress) { if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
if (pressedKeys.size() < 3) {
switch (mouseEvent->button()) { switch (mouseEvent->button()) {
case Qt::LeftButton: case Qt::LeftButton:
pressedKeys.insert("leftbutton"); SetMapping("leftbutton");
break; break;
case Qt::RightButton: case Qt::RightButton:
pressedKeys.insert("rightbutton"); SetMapping("rightbutton");
break; break;
case Qt::MiddleButton: case Qt::MiddleButton:
pressedKeys.insert("middlebutton"); SetMapping("middlebutton");
break; break;
default: default:
break; break;
} }
return true; return true;
} }
}
const QList<QPushButton*> AxisList = { const QList<QPushButton*> AxisList = {
ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->LStickRightButton, ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->LStickRightButton,
@ -983,17 +953,16 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
if (event->type() == QEvent::Wheel) { if (event->type() == QEvent::Wheel) {
QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event); QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event);
if (pressedKeys.size() < 3) {
if (wheelEvent->angleDelta().y() > 5) { if (wheelEvent->angleDelta().y() > 5) {
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
pressedKeys.insert("mousewheelup"); SetMapping("mousewheelup");
} else { } else {
QMessageBox::information(this, tr("Cannot set mapping"), QMessageBox::information(this, tr("Cannot set mapping"),
tr("Mousewheel cannot be mapped to stick outputs")); tr("Mousewheel cannot be mapped to stick outputs"));
} }
} else if (wheelEvent->angleDelta().y() < -5) { } else if (wheelEvent->angleDelta().y() < -5) {
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
pressedKeys.insert("mousewheeldown"); SetMapping("mousewheeldown");
} else { } else {
QMessageBox::information(this, tr("Cannot set mapping"), QMessageBox::information(this, tr("Cannot set mapping"),
tr("Mousewheel cannot be mapped to stick outputs")); tr("Mousewheel cannot be mapped to stick outputs"));
@ -1003,9 +972,9 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
// QT changes scrolling to horizontal for all widgets with the alt modifier // QT changes scrolling to horizontal for all widgets with the alt modifier
if (Qt::AltModifier & QApplication::keyboardModifiers()) { if (Qt::AltModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("mousewheelup"); SetMapping("mousewheelup");
} else { } else {
pressedKeys.insert("mousewheelright"); SetMapping("mousewheelright");
} }
} else { } else {
QMessageBox::information(this, tr("Cannot set mapping"), QMessageBox::information(this, tr("Cannot set mapping"),
@ -1014,18 +983,18 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) {
} else if (wheelEvent->angleDelta().x() < -5) { } else if (wheelEvent->angleDelta().x() < -5) {
if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) {
if (Qt::AltModifier & QApplication::keyboardModifiers()) { if (Qt::AltModifier & QApplication::keyboardModifiers()) {
pressedKeys.insert("mousewheeldown"); SetMapping("mousewheeldown");
} else { } else {
pressedKeys.insert("mousewheelleft"); SetMapping("mousewheelleft");
} }
} else { } else {
QMessageBox::information(this, tr("Cannot set mapping"), QMessageBox::information(this, tr("Cannot set mapping"),
tr("Mousewheel cannot be mapped to stick outputs")); tr("Mousewheel cannot be mapped to stick outputs"));
} }
} }
return true;
} }
} }
return QDialog::eventFilter(obj, event); return QDialog::eventFilter(obj, event);
} }

View file

@ -25,22 +25,6 @@ private:
std::unique_ptr<Ui::KBMSettings> ui; std::unique_ptr<Ui::KBMSettings> ui;
std::shared_ptr<GameInfoClass> m_game_info; std::shared_ptr<GameInfoClass> m_game_info;
#ifdef _WIN32
const int lctrl = 29;
const int rctrl = 57373;
const int lalt = 56;
const int ralt = 57400;
const int lshift = 42;
const int rshift = 54;
#else
const int lctrl = 37;
const int rctrl = 105;
const int lalt = 64;
const int ralt = 108;
const int lshift = 50;
const int rshift = 62;
#endif
bool eventFilter(QObject* obj, QEvent* event) override; bool eventFilter(QObject* obj, QEvent* event) override;
void ButtonConnects(); void ButtonConnects();
void SetUIValuestoMappings(std::string config_id); void SetUIValuestoMappings(std::string config_id);
@ -49,7 +33,6 @@ private:
void EnableMappingButtons(); void EnableMappingButtons();
void SetMapping(QString input); void SetMapping(QString input);
QSet<QString> pressedKeys;
bool EnableMapping = false; bool EnableMapping = false;
bool MappingCompleted = false; bool MappingCompleted = false;
bool HelpWindowOpen = false; bool HelpWindowOpen = false;

View file

@ -335,7 +335,8 @@ void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) {
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
} }
if (info.has_discard) { if (info.has_discard) {
ctx.AddCapability(spv::Capability::DemoteToHelperInvocation); ctx.AddExtension("SPV_EXT_demote_to_helper_invocation");
ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
} }
if (info.stores.GetAny(IR::Attribute::Depth)) { if (info.stores.GetAny(IR::Attribute::Depth)) {
ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);

View file

@ -38,7 +38,6 @@ Id BufferAtomicU32BoundsCheck(EmitContext& ctx, Id index, Id buffer_size, auto e
const Id ib_label = ctx.OpLabel(); const Id ib_label = ctx.OpLabel();
const Id oob_label = ctx.OpLabel(); const Id oob_label = ctx.OpLabel();
const Id end_label = ctx.OpLabel(); const Id end_label = ctx.OpLabel();
ctx.OpSelectionMerge(end_label, spv::SelectionControlMask::MaskNone);
ctx.OpBranchConditional(in_bounds, ib_label, oob_label); ctx.OpBranchConditional(in_bounds, ib_label, oob_label);
ctx.AddLabel(ib_label); ctx.AddLabel(ib_label);
const Id ib_result = emit_func(); const Id ib_result = emit_func();

View file

@ -64,6 +64,10 @@ Id EmitBitCastU32F32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.U32[1], value); return ctx.OpBitcast(ctx.U32[1], value);
} }
Id EmitBitCastU64F64(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.U64, value);
}
Id EmitBitCastF16U16(EmitContext& ctx, Id value) { Id EmitBitCastF16U16(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.F16[1], value); return ctx.OpBitcast(ctx.F16[1], value);
} }
@ -72,6 +76,10 @@ Id EmitBitCastF32U32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.F32[1], value); return ctx.OpBitcast(ctx.F32[1], value);
} }
void EmitBitCastF64U64(EmitContext&) {
UNREACHABLE_MSG("SPIR-V Instruction");
}
Id EmitPackUint2x32(EmitContext& ctx, Id value) { Id EmitPackUint2x32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.U64, value); return ctx.OpBitcast(ctx.U64, value);
} }
@ -80,14 +88,10 @@ Id EmitUnpackUint2x32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.U32[2], value); return ctx.OpBitcast(ctx.U32[2], value);
} }
Id EmitPackDouble2x32(EmitContext& ctx, Id value) { Id EmitPackFloat2x32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.F64[1], value); return ctx.OpBitcast(ctx.F64[1], value);
} }
Id EmitUnpackDouble2x32(EmitContext& ctx, Id value) {
return ctx.OpBitcast(ctx.U32[2], value);
}
Id EmitPackUnorm2x16(EmitContext& ctx, Id value) { Id EmitPackUnorm2x16(EmitContext& ctx, Id value) {
return ctx.OpPackUnorm2x16(ctx.U32[1], value); return ctx.OpPackUnorm2x16(ctx.U32[1], value);
} }

View file

@ -202,12 +202,13 @@ Id EmitSelectF32(EmitContext& ctx, Id cond, Id true_value, Id false_value);
Id EmitSelectF64(EmitContext& ctx, Id cond, Id true_value, Id false_value); Id EmitSelectF64(EmitContext& ctx, Id cond, Id true_value, Id false_value);
Id EmitBitCastU16F16(EmitContext& ctx, Id value); Id EmitBitCastU16F16(EmitContext& ctx, Id value);
Id EmitBitCastU32F32(EmitContext& ctx, Id value); Id EmitBitCastU32F32(EmitContext& ctx, Id value);
Id EmitBitCastU64F64(EmitContext& ctx, Id value);
Id EmitBitCastF16U16(EmitContext& ctx, Id value); Id EmitBitCastF16U16(EmitContext& ctx, Id value);
Id EmitBitCastF32U32(EmitContext& ctx, Id value); Id EmitBitCastF32U32(EmitContext& ctx, Id value);
void EmitBitCastF64U64(EmitContext& ctx);
Id EmitPackUint2x32(EmitContext& ctx, Id value); Id EmitPackUint2x32(EmitContext& ctx, Id value);
Id EmitUnpackUint2x32(EmitContext& ctx, Id value); Id EmitUnpackUint2x32(EmitContext& ctx, Id value);
Id EmitPackDouble2x32(EmitContext& ctx, Id value); Id EmitPackFloat2x32(EmitContext& ctx, Id value);
Id EmitUnpackDouble2x32(EmitContext& ctx, Id value);
Id EmitPackUnorm2x16(EmitContext& ctx, Id value); Id EmitPackUnorm2x16(EmitContext& ctx, Id value);
Id EmitUnpackUnorm2x16(EmitContext& ctx, Id value); Id EmitUnpackUnorm2x16(EmitContext& ctx, Id value);
Id EmitPackSnorm2x16(EmitContext& ctx, Id value); Id EmitPackSnorm2x16(EmitContext& ctx, Id value);

View file

@ -336,7 +336,7 @@ T Translator::GetSrc64(const InstOperand& operand) {
const auto value_lo = ir.GetVectorReg(IR::VectorReg(operand.code)); const auto value_lo = ir.GetVectorReg(IR::VectorReg(operand.code));
const auto value_hi = ir.GetVectorReg(IR::VectorReg(operand.code + 1)); const auto value_hi = ir.GetVectorReg(IR::VectorReg(operand.code + 1));
if constexpr (is_float) { if constexpr (is_float) {
value = ir.PackDouble2x32(ir.CompositeConstruct(value_lo, value_hi)); value = ir.PackFloat2x32(ir.CompositeConstruct(value_lo, value_hi));
} else { } else {
value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi)); value = ir.PackUint2x32(ir.CompositeConstruct(value_lo, value_hi));
} }
@ -444,9 +444,10 @@ void Translator::SetDst64(const InstOperand& operand, const IR::U64F64& value_ra
value_untyped = ir.FPSaturate(value_raw); value_untyped = ir.FPSaturate(value_raw);
} }
} }
const IR::U64 value =
is_float ? ir.BitCast<IR::U64>(IR::F64{value_untyped}) : IR::U64{value_untyped};
const IR::Value unpacked{is_float ? ir.UnpackDouble2x32(IR::F64{value_untyped}) const IR::Value unpacked{ir.UnpackUint2x32(value)};
: ir.UnpackUint2x32(IR::U64{value_untyped})};
const IR::U32 lo{ir.CompositeExtract(unpacked, 0U)}; const IR::U32 lo{ir.CompositeExtract(unpacked, 0U)};
const IR::U32 hi{ir.CompositeExtract(unpacked, 1U)}; const IR::U32 hi{ir.CompositeExtract(unpacked, 1U)};
switch (operand.field) { switch (operand.field) {

View file

@ -513,13 +513,13 @@ void Translator::V_LSHLREV_B32(const GcnInst& inst) {
void Translator::V_AND_B32(const GcnInst& inst) { void Translator::V_AND_B32(const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{ir.GetVectorReg(IR::VectorReg(inst.src[1].code))};
SetDst(inst.dst[0], ir.BitwiseAnd(src0, src1)); SetDst(inst.dst[0], ir.BitwiseAnd(src0, src1));
} }
void Translator::V_OR_B32(bool is_xor, const GcnInst& inst) { void Translator::V_OR_B32(bool is_xor, const GcnInst& inst) {
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{ir.GetVectorReg(IR::VectorReg(inst.src[1].code))};
SetDst(inst.dst[0], is_xor ? ir.BitwiseXor(src0, src1) : IR::U32(ir.BitwiseOr(src0, src1))); SetDst(inst.dst[0], is_xor ? ir.BitwiseXor(src0, src1) : IR::U32(ir.BitwiseOr(src0, src1)));
} }
@ -579,7 +579,7 @@ void Translator::V_MBCNT_U32_B32(bool is_low, const GcnInst& inst) {
void Translator::V_ADD_I32(const GcnInst& inst) { void Translator::V_ADD_I32(const GcnInst& inst) {
// Signed or unsigned components // Signed or unsigned components
const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 src0{GetSrc(inst.src[0])};
const IR::U32 src1{GetSrc(inst.src[1])}; const IR::U32 src1{ir.GetVectorReg(IR::VectorReg(inst.src[1].code))};
const IR::U32 result{ir.IAdd(src0, src1)}; const IR::U32 result{ir.IAdd(src0, src1)};
SetDst(inst.dst[0], result); SetDst(inst.dst[0], result);

View file

@ -84,6 +84,16 @@ IR::F16 IREmitter::BitCast<IR::F16, IR::U16>(const IR::U16& value) {
return Inst<IR::F16>(Opcode::BitCastF16U16, value); return Inst<IR::F16>(Opcode::BitCastF16U16, value);
} }
template <>
IR::U64 IREmitter::BitCast<IR::U64, IR::F64>(const IR::F64& value) {
return Inst<IR::U64>(Opcode::BitCastU64F64, value);
}
template <>
IR::F64 IREmitter::BitCast<IR::F64, IR::U64>(const IR::U64& value) {
return Inst<IR::F64>(Opcode::BitCastF64U64, value);
}
U1 IREmitter::ConditionRef(const U1& value) { U1 IREmitter::ConditionRef(const U1& value) {
return Inst<U1>(Opcode::ConditionRef, value); return Inst<U1>(Opcode::ConditionRef, value);
} }
@ -831,12 +841,8 @@ Value IREmitter::UnpackUint2x32(const U64& value) {
return Inst<Value>(Opcode::UnpackUint2x32, value); return Inst<Value>(Opcode::UnpackUint2x32, value);
} }
F64 IREmitter::PackDouble2x32(const Value& vector) { F64 IREmitter::PackFloat2x32(const Value& vector) {
return Inst<F64>(Opcode::PackDouble2x32, vector); return Inst<F64>(Opcode::PackFloat2x32, vector);
}
Value IREmitter::UnpackDouble2x32(const F64& value) {
return Inst<Value>(Opcode::UnpackDouble2x32, value);
} }
U32 IREmitter::Pack2x16(const AmdGpu::NumberFormat number_format, const Value& vector) { U32 IREmitter::Pack2x16(const AmdGpu::NumberFormat number_format, const Value& vector) {

View file

@ -181,8 +181,7 @@ public:
[[nodiscard]] U64 PackUint2x32(const Value& vector); [[nodiscard]] U64 PackUint2x32(const Value& vector);
[[nodiscard]] Value UnpackUint2x32(const U64& value); [[nodiscard]] Value UnpackUint2x32(const U64& value);
[[nodiscard]] F64 PackDouble2x32(const Value& vector); [[nodiscard]] F64 PackFloat2x32(const Value& vector);
[[nodiscard]] Value UnpackDouble2x32(const F64& value);
[[nodiscard]] U32 Pack2x16(AmdGpu::NumberFormat number_format, const Value& vector); [[nodiscard]] U32 Pack2x16(AmdGpu::NumberFormat number_format, const Value& vector);
[[nodiscard]] Value Unpack2x16(AmdGpu::NumberFormat number_format, const U32& value); [[nodiscard]] Value Unpack2x16(AmdGpu::NumberFormat number_format, const U32& value);

View file

@ -191,13 +191,14 @@ OPCODE(SelectF64, F64, U1,
// Bitwise conversions // Bitwise conversions
OPCODE(BitCastU16F16, U16, F16, ) OPCODE(BitCastU16F16, U16, F16, )
OPCODE(BitCastU32F32, U32, F32, ) OPCODE(BitCastU32F32, U32, F32, )
OPCODE(BitCastU64F64, U64, F64, )
OPCODE(BitCastF16U16, F16, U16, ) OPCODE(BitCastF16U16, F16, U16, )
OPCODE(BitCastF32U32, F32, U32, ) OPCODE(BitCastF32U32, F32, U32, )
OPCODE(BitCastF64U64, F64, U64, )
OPCODE(PackUint2x32, U64, U32x2, ) OPCODE(PackUint2x32, U64, U32x2, )
OPCODE(UnpackUint2x32, U32x2, U64, ) OPCODE(UnpackUint2x32, U32x2, U64, )
OPCODE(PackDouble2x32, F64, U32x2, ) OPCODE(PackFloat2x32, F64, F32x2, )
OPCODE(UnpackDouble2x32, U32x2, F64, )
OPCODE(PackUnorm2x16, U32, F32x2, ) OPCODE(PackUnorm2x16, U32, F32x2, )
OPCODE(UnpackUnorm2x16, F32x2, U32, ) OPCODE(UnpackUnorm2x16, F32x2, U32, )

View file

@ -21,7 +21,6 @@ void ReadLaneEliminationPass(IR::Program& program);
void ResourceTrackingPass(IR::Program& program); void ResourceTrackingPass(IR::Program& program);
void CollectShaderInfoPass(IR::Program& program); void CollectShaderInfoPass(IR::Program& program);
void LowerBufferFormatToRaw(IR::Program& program); void LowerBufferFormatToRaw(IR::Program& program);
void LowerFp64ToFp32(IR::Program& program);
void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info); void RingAccessElimination(const IR::Program& program, const RuntimeInfo& runtime_info);
void TessellationPreprocess(IR::Program& program, RuntimeInfo& runtime_info); void TessellationPreprocess(IR::Program& program, RuntimeInfo& runtime_info);
void HullShaderTransform(IR::Program& program, RuntimeInfo& runtime_info); void HullShaderTransform(IR::Program& program, RuntimeInfo& runtime_info);

View file

@ -196,18 +196,13 @@ static void LowerBufferFormatInst(IR::Block& block, IR::Inst& inst, Info& info)
const auto buffer{desc.GetSharp(info)}; const auto buffer{desc.GetSharp(info)};
const auto is_inst_typed = flags.inst_data_fmt != AmdGpu::DataFormat::FormatInvalid; const auto is_inst_typed = flags.inst_data_fmt != AmdGpu::DataFormat::FormatInvalid;
const auto data_format = const auto data_format = is_inst_typed ? flags.inst_data_fmt.Value() : buffer.GetDataFmt();
is_inst_typed ? AmdGpu::RemapDataFormat(flags.inst_data_fmt.Value()) : buffer.GetDataFmt(); const auto num_format = is_inst_typed ? flags.inst_num_fmt.Value() : buffer.GetNumberFmt();
const auto format_info = FormatInfo{ const auto format_info = FormatInfo{
.data_format = data_format, .data_format = data_format,
.num_format = is_inst_typed .num_format = num_format,
? AmdGpu::RemapNumberFormat(flags.inst_num_fmt.Value(), data_format) .swizzle = is_inst_typed ? AmdGpu::IdentityMapping : buffer.DstSelect(),
: buffer.GetNumberFmt(), .num_conversion = AmdGpu::MapNumberConversion(num_format),
.swizzle = is_inst_typed
? AmdGpu::RemapSwizzle(flags.inst_data_fmt.Value(), AmdGpu::IdentityMapping)
: buffer.DstSelect(),
.num_conversion = is_inst_typed ? AmdGpu::MapNumberConversion(flags.inst_num_fmt.Value())
: buffer.GetNumberConversion(),
.num_components = AmdGpu::NumComponents(data_format), .num_components = AmdGpu::NumComponents(data_format),
}; };

View file

@ -1,186 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "shader_recompiler/info.h"
#include "shader_recompiler/ir/basic_block.h"
#include "shader_recompiler/ir/ir_emitter.h"
#include "shader_recompiler/ir/program.h"
namespace Shader::Optimization {
constexpr s32 F64ToF32Exp = +1023 - 127;
constexpr s32 F32ToF64Exp = +127 - 1023;
static IR::F32 PackedF64ToF32(IR::IREmitter& ir, const IR::Value& packed) {
const IR::U32 lo{ir.CompositeExtract(packed, 0)};
const IR::U32 hi{ir.CompositeExtract(packed, 1)};
const IR::U32 sign{ir.BitFieldExtract(hi, ir.Imm32(31), ir.Imm32(1))};
const IR::U32 exp{ir.BitFieldExtract(hi, ir.Imm32(20), ir.Imm32(11))};
const IR::U32 mantissa_hi{ir.BitFieldExtract(hi, ir.Imm32(0), ir.Imm32(20))};
const IR::U32 mantissa_lo{ir.BitFieldExtract(lo, ir.Imm32(29), ir.Imm32(3))};
const IR::U32 mantissa{
ir.BitwiseOr(ir.ShiftLeftLogical(mantissa_hi, ir.Imm32(3)), mantissa_lo)};
const IR::U32 exp_if_subnorm{
ir.Select(ir.IEqual(exp, ir.Imm32(0)), ir.Imm32(0), ir.IAdd(exp, ir.Imm32(F64ToF32Exp)))};
const IR::U32 exp_if_infnan{
ir.Select(ir.IEqual(exp, ir.Imm32(0x7ff)), ir.Imm32(0xff), exp_if_subnorm)};
const IR::U32 result{
ir.BitwiseOr(ir.ShiftLeftLogical(sign, ir.Imm32(31)),
ir.BitwiseOr(ir.ShiftLeftLogical(exp_if_infnan, ir.Imm32(23)), mantissa))};
return ir.BitCast<IR::F32>(result);
}
IR::Value F32ToPackedF64(IR::IREmitter& ir, const IR::Value& raw) {
const IR::U32 value{ir.BitCast<IR::U32>(IR::F32(raw))};
const IR::U32 sign{ir.BitFieldExtract(value, ir.Imm32(31), ir.Imm32(1))};
const IR::U32 exp{ir.BitFieldExtract(value, ir.Imm32(23), ir.Imm32(8))};
const IR::U32 mantissa{ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(23))};
const IR::U32 mantissa_hi{ir.BitFieldExtract(mantissa, ir.Imm32(3), ir.Imm32(20))};
const IR::U32 mantissa_lo{ir.BitFieldExtract(mantissa, ir.Imm32(0), ir.Imm32(3))};
const IR::U32 exp_if_subnorm{
ir.Select(ir.IEqual(exp, ir.Imm32(0)), ir.Imm32(0), ir.IAdd(exp, ir.Imm32(F32ToF64Exp)))};
const IR::U32 exp_if_infnan{
ir.Select(ir.IEqual(exp, ir.Imm32(0xff)), ir.Imm32(0x7ff), exp_if_subnorm)};
const IR::U32 lo{ir.ShiftLeftLogical(mantissa_lo, ir.Imm32(29))};
const IR::U32 hi{
ir.BitwiseOr(ir.ShiftLeftLogical(sign, ir.Imm32(31)),
ir.BitwiseOr(ir.ShiftLeftLogical(exp_if_infnan, ir.Imm32(20)), mantissa_hi))};
return ir.CompositeConstruct(lo, hi);
}
static IR::Opcode Replace(IR::Opcode op) {
switch (op) {
case IR::Opcode::CompositeConstructF64x2:
return IR::Opcode::CompositeConstructF32x2;
case IR::Opcode::CompositeConstructF64x3:
return IR::Opcode::CompositeConstructF32x3;
case IR::Opcode::CompositeConstructF64x4:
return IR::Opcode::CompositeConstructF32x4;
case IR::Opcode::CompositeExtractF64x2:
return IR::Opcode::CompositeExtractF32x2;
case IR::Opcode::CompositeExtractF64x3:
return IR::Opcode::CompositeExtractF32x3;
case IR::Opcode::CompositeExtractF64x4:
return IR::Opcode::CompositeExtractF32x4;
case IR::Opcode::CompositeInsertF64x2:
return IR::Opcode::CompositeInsertF32x2;
case IR::Opcode::CompositeInsertF64x3:
return IR::Opcode::CompositeInsertF32x3;
case IR::Opcode::CompositeInsertF64x4:
return IR::Opcode::CompositeInsertF32x4;
case IR::Opcode::CompositeShuffleF64x2:
return IR::Opcode::CompositeShuffleF32x2;
case IR::Opcode::CompositeShuffleF64x3:
return IR::Opcode::CompositeShuffleF32x3;
case IR::Opcode::CompositeShuffleF64x4:
return IR::Opcode::CompositeShuffleF32x4;
case IR::Opcode::SelectF64:
return IR::Opcode::SelectF64;
case IR::Opcode::FPAbs64:
return IR::Opcode::FPAbs32;
case IR::Opcode::FPAdd64:
return IR::Opcode::FPAdd32;
case IR::Opcode::FPFma64:
return IR::Opcode::FPFma32;
case IR::Opcode::FPMax64:
return IR::Opcode::FPMax32;
case IR::Opcode::FPMin64:
return IR::Opcode::FPMin32;
case IR::Opcode::FPMul64:
return IR::Opcode::FPMul32;
case IR::Opcode::FPDiv64:
return IR::Opcode::FPDiv32;
case IR::Opcode::FPNeg64:
return IR::Opcode::FPNeg32;
case IR::Opcode::FPRecip64:
return IR::Opcode::FPRecip32;
case IR::Opcode::FPRecipSqrt64:
return IR::Opcode::FPRecipSqrt32;
case IR::Opcode::FPSaturate64:
return IR::Opcode::FPSaturate32;
case IR::Opcode::FPClamp64:
return IR::Opcode::FPClamp32;
case IR::Opcode::FPRoundEven64:
return IR::Opcode::FPRoundEven32;
case IR::Opcode::FPFloor64:
return IR::Opcode::FPFloor32;
case IR::Opcode::FPCeil64:
return IR::Opcode::FPCeil32;
case IR::Opcode::FPTrunc64:
return IR::Opcode::FPTrunc32;
case IR::Opcode::FPFract64:
return IR::Opcode::FPFract32;
case IR::Opcode::FPFrexpSig64:
return IR::Opcode::FPFrexpSig32;
case IR::Opcode::FPFrexpExp64:
return IR::Opcode::FPFrexpExp32;
case IR::Opcode::FPOrdEqual64:
return IR::Opcode::FPOrdEqual32;
case IR::Opcode::FPUnordEqual64:
return IR::Opcode::FPUnordEqual32;
case IR::Opcode::FPOrdNotEqual64:
return IR::Opcode::FPOrdNotEqual32;
case IR::Opcode::FPUnordNotEqual64:
return IR::Opcode::FPUnordNotEqual32;
case IR::Opcode::FPOrdLessThan64:
return IR::Opcode::FPOrdLessThan32;
case IR::Opcode::FPUnordLessThan64:
return IR::Opcode::FPUnordLessThan32;
case IR::Opcode::FPOrdGreaterThan64:
return IR::Opcode::FPOrdGreaterThan32;
case IR::Opcode::FPUnordGreaterThan64:
return IR::Opcode::FPUnordGreaterThan32;
case IR::Opcode::FPOrdLessThanEqual64:
return IR::Opcode::FPOrdLessThanEqual32;
case IR::Opcode::FPUnordLessThanEqual64:
return IR::Opcode::FPUnordLessThanEqual32;
case IR::Opcode::FPOrdGreaterThanEqual64:
return IR::Opcode::FPOrdGreaterThanEqual32;
case IR::Opcode::FPUnordGreaterThanEqual64:
return IR::Opcode::FPUnordGreaterThanEqual32;
case IR::Opcode::FPIsNan64:
return IR::Opcode::FPIsNan32;
case IR::Opcode::FPIsInf64:
return IR::Opcode::FPIsInf32;
case IR::Opcode::ConvertS32F64:
return IR::Opcode::ConvertS32F32;
case IR::Opcode::ConvertF32F64:
return IR::Opcode::Identity;
case IR::Opcode::ConvertF64F32:
return IR::Opcode::Identity;
case IR::Opcode::ConvertF64S32:
return IR::Opcode::ConvertF32S32;
case IR::Opcode::ConvertF64U32:
return IR::Opcode::ConvertF32U32;
default:
return op;
}
}
static void Lower(IR::Block& block, IR::Inst& inst) {
switch (inst.GetOpcode()) {
case IR::Opcode::PackDouble2x32: {
IR::IREmitter ir(block, IR::Block::InstructionList::s_iterator_to(inst));
inst.ReplaceUsesWith(PackedF64ToF32(ir, inst.Arg(0)));
break;
}
case IR::Opcode::UnpackDouble2x32: {
IR::IREmitter ir(block, IR::Block::InstructionList::s_iterator_to(inst));
inst.ReplaceUsesWith(F32ToPackedF64(ir, inst.Arg(0)));
break;
}
default:
inst.ReplaceOpcode(Replace(inst.GetOpcode()));
break;
}
}
void LowerFp64ToFp32(IR::Program& program) {
for (IR::Block* const block : program.blocks) {
for (IR::Inst& inst : block->Instructions()) {
Lower(*block, inst);
}
}
}
} // namespace Shader::Optimization

View file

@ -44,8 +44,7 @@ void Visit(Info& info, const IR::Inst& inst) {
case IR::Opcode::BitCastF16U16: case IR::Opcode::BitCastF16U16:
info.uses_fp16 = true; info.uses_fp16 = true;
break; break;
case IR::Opcode::PackDouble2x32: case IR::Opcode::BitCastU64F64:
case IR::Opcode::UnpackDouble2x32:
info.uses_fp64 = true; info.uses_fp64 = true;
break; break;
case IR::Opcode::ImageWrite: case IR::Opcode::ImageWrite:

View file

@ -15,7 +15,6 @@ struct Profile {
bool support_int8{}; bool support_int8{};
bool support_int16{}; bool support_int16{};
bool support_int64{}; bool support_int64{};
bool support_float64{};
bool support_vertex_instance_id{}; bool support_vertex_instance_id{};
bool support_float_controls{}; bool support_float_controls{};
bool support_separate_denorm_behavior{}; bool support_separate_denorm_behavior{};

View file

@ -60,9 +60,6 @@ IR::Program TranslateProgram(std::span<const u32> code, Pools& pools, Info& info
program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front()); program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front());
// Run optimization passes // Run optimization passes
if (!profile.support_float64) {
Shader::Optimization::LowerFp64ToFp32(program);
}
Shader::Optimization::SsaRewritePass(program.post_order_blocks); Shader::Optimization::SsaRewritePass(program.post_order_blocks);
Shader::Optimization::ConstantPropagationPass(program.post_order_blocks); Shader::Optimization::ConstantPropagationPass(program.post_order_blocks);
Shader::Optimization::IdentityRemovalPass(program.blocks); Shader::Optimization::IdentityRemovalPass(program.blocks);

View file

@ -14,7 +14,7 @@
namespace Vulkan::HostPasses { namespace Vulkan::HostPasses {
void PostProcessingPass::Create(vk::Device device, const vk::Format surface_format) { void PostProcessingPass::Create(vk::Device device) {
static const std::array pp_shaders{ static const std::array pp_shaders{
HostShaders::FS_TRI_VERT, HostShaders::FS_TRI_VERT,
HostShaders::POST_PROCESS_FRAG, HostShaders::POST_PROCESS_FRAG,
@ -76,9 +76,9 @@ void PostProcessingPass::Create(vk::Device device, const vk::Format surface_form
Check<"create pp pipeline layout">(device.createPipelineLayoutUnique(layout_info)); Check<"create pp pipeline layout">(device.createPipelineLayoutUnique(layout_info));
const std::array pp_color_formats{ const std::array pp_color_formats{
surface_format, vk::Format::eB8G8R8A8Unorm, // swapchain.GetSurfaceFormat().format,
}; };
const vk::PipelineRenderingCreateInfo pipeline_rendering_ci{ const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci{
.colorAttachmentCount = pp_color_formats.size(), .colorAttachmentCount = pp_color_formats.size(),
.pColorAttachmentFormats = pp_color_formats.data(), .pColorAttachmentFormats = pp_color_formats.data(),
}; };

View file

@ -19,7 +19,7 @@ public:
u32 hdr = 0; u32 hdr = 0;
}; };
void Create(vk::Device device, vk::Format surface_format); void Create(vk::Device device);
void Render(vk::CommandBuffer cmdbuf, vk::ImageView input, vk::Extent2D input_size, void Render(vk::CommandBuffer cmdbuf, vk::ImageView input, vk::Extent2D input_size,
Frame& output, Settings settings); Frame& output, Settings settings);

View file

@ -122,21 +122,21 @@ GraphicsPipeline::GraphicsPipeline(
}; };
boost::container::static_vector<vk::DynamicState, 20> dynamic_states = { boost::container::static_vector<vk::DynamicState, 20> dynamic_states = {
vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount, vk::DynamicState::eViewportWithCountEXT, vk::DynamicState::eScissorWithCountEXT,
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable, vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnableEXT,
vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp, vk::DynamicState::eDepthWriteEnableEXT, vk::DynamicState::eDepthCompareOpEXT,
vk::DynamicState::eDepthBiasEnable, vk::DynamicState::eDepthBias, vk::DynamicState::eDepthBiasEnableEXT, vk::DynamicState::eDepthBias,
vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference, vk::DynamicState::eStencilTestEnableEXT, vk::DynamicState::eStencilReference,
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode, vk::DynamicState::eStencilOpEXT, vk::DynamicState::eCullModeEXT,
vk::DynamicState::eFrontFace, vk::DynamicState::eFrontFaceEXT,
}; };
if (instance.IsPrimitiveRestartDisableSupported()) { if (instance.IsPrimitiveRestartDisableSupported()) {
dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnable); dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnableEXT);
} }
if (instance.IsDepthBoundsSupported()) { if (instance.IsDepthBoundsSupported()) {
dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnable); dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnableEXT);
dynamic_states.push_back(vk::DynamicState::eDepthBounds); dynamic_states.push_back(vk::DynamicState::eDepthBounds);
} }
if (instance.IsDynamicColorWriteMaskSupported()) { if (instance.IsDynamicColorWriteMaskSupported()) {
@ -145,7 +145,7 @@ GraphicsPipeline::GraphicsPipeline(
if (instance.IsVertexInputDynamicState()) { if (instance.IsVertexInputDynamicState()) {
dynamic_states.push_back(vk::DynamicState::eVertexInputEXT); dynamic_states.push_back(vk::DynamicState::eVertexInputEXT);
} else if (!vertex_bindings.empty()) { } else if (!vertex_bindings.empty()) {
dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride); dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStrideEXT);
} }
const vk::PipelineDynamicStateCreateInfo dynamic_info = { const vk::PipelineDynamicStateCreateInfo dynamic_info = {
@ -212,7 +212,7 @@ GraphicsPipeline::GraphicsPipeline(
}); });
} }
const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci = {
.colorAttachmentCount = key.num_color_attachments, .colorAttachmentCount = key.num_color_attachments,
.pColorAttachmentFormats = key.color_formats.data(), .pColorAttachmentFormats = key.color_formats.data(),
.depthAttachmentFormat = key.depth_format, .depthAttachmentFormat = key.depth_format,

View file

@ -203,11 +203,9 @@ std::string Instance::GetDriverVersionName() {
} }
bool Instance::CreateDevice() { bool Instance::CreateDevice() {
const vk::StructureChain feature_chain = const vk::StructureChain feature_chain = physical_device.getFeatures2<
physical_device vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features,
.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceRobustness2FeaturesEXT,
vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceVulkan13Features,
vk::PhysicalDeviceRobustness2FeaturesEXT,
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT, vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT,
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
vk::PhysicalDevicePortabilitySubsetFeaturesKHR>(); vk::PhysicalDevicePortabilitySubsetFeaturesKHR>();
@ -242,6 +240,18 @@ bool Instance::CreateDevice() {
return false; return false;
}; };
// These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2
// with extensions.
ASSERT(add_extension(VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME));
ASSERT(add_extension(VK_EXT_TOOLING_INFO_EXTENSION_NAME) ||
driver_id == vk::DriverId::eIntelProprietaryWindows);
ASSERT(add_extension(VK_KHR_MAINTENANCE_4_EXTENSION_NAME));
// Required // Required
ASSERT(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); ASSERT(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME));
ASSERT(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)); ASSERT(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME));
@ -314,7 +324,6 @@ bool Instance::CreateDevice() {
feature_chain.get<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>(); feature_chain.get<vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT>();
const auto vk11_features = feature_chain.get<vk::PhysicalDeviceVulkan11Features>(); const auto vk11_features = feature_chain.get<vk::PhysicalDeviceVulkan11Features>();
const auto vk12_features = feature_chain.get<vk::PhysicalDeviceVulkan12Features>(); const auto vk12_features = feature_chain.get<vk::PhysicalDeviceVulkan12Features>();
const auto vk13_features = feature_chain.get<vk::PhysicalDeviceVulkan13Features>();
vk::StructureChain device_chain = { vk::StructureChain device_chain = {
vk::DeviceCreateInfo{ vk::DeviceCreateInfo{
.queueCreateInfoCount = 1u, .queueCreateInfoCount = 1u,
@ -332,7 +341,6 @@ bool Instance::CreateDevice() {
.logicOp = features.logicOp, .logicOp = features.logicOp,
.depthBiasClamp = features.depthBiasClamp, .depthBiasClamp = features.depthBiasClamp,
.fillModeNonSolid = features.fillModeNonSolid, .fillModeNonSolid = features.fillModeNonSolid,
.depthBounds = features.depthBounds,
.multiViewport = features.multiViewport, .multiViewport = features.multiViewport,
.samplerAnisotropy = features.samplerAnisotropy, .samplerAnisotropy = features.samplerAnisotropy,
.vertexPipelineStoresAndAtomics = features.vertexPipelineStoresAndAtomics, .vertexPipelineStoresAndAtomics = features.vertexPipelineStoresAndAtomics,
@ -364,14 +372,26 @@ bool Instance::CreateDevice() {
.hostQueryReset = vk12_features.hostQueryReset, .hostQueryReset = vk12_features.hostQueryReset,
.timelineSemaphore = vk12_features.timelineSemaphore, .timelineSemaphore = vk12_features.timelineSemaphore,
}, },
vk::PhysicalDeviceVulkan13Features{ // Vulkan 1.3 promoted extensions
.robustImageAccess = vk13_features.robustImageAccess, vk::PhysicalDeviceDynamicRenderingFeaturesKHR{
.shaderDemoteToHelperInvocation = vk13_features.shaderDemoteToHelperInvocation, .dynamicRendering = true,
.synchronization2 = vk13_features.synchronization2,
.dynamicRendering = vk13_features.dynamicRendering,
.maintenance4 = vk13_features.maintenance4,
}, },
// Extensions vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT{
.shaderDemoteToHelperInvocation = true,
},
vk::PhysicalDeviceSynchronization2Features{
.synchronization2 = true,
},
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT{
.extendedDynamicState = true,
},
vk::PhysicalDeviceExtendedDynamicState2FeaturesEXT{
.extendedDynamicState2 = true,
},
vk::PhysicalDeviceMaintenance4FeaturesKHR{
.maintenance4 = true,
},
// Other extensions
vk::PhysicalDeviceCustomBorderColorFeaturesEXT{ vk::PhysicalDeviceCustomBorderColorFeaturesEXT{
.customBorderColors = true, .customBorderColors = true,
.customBorderColorWithoutFormat = true, .customBorderColorWithoutFormat = true,
@ -522,14 +542,12 @@ void Instance::CollectDeviceParameters() {
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions); LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions);
} }
void Instance::CollectToolingInfo() const { void Instance::CollectToolingInfo() {
if (driver_id == vk::DriverId::eAmdProprietary || if (GetDriverID() == vk::DriverId::eAmdProprietary) {
driver_id == vk::DriverId::eIntelProprietaryWindows) { // Currently causes issues with Reshade on AMD proprietary, disabled until fix released.
// AMD: Causes issues with Reshade.
// Intel: Causes crash on start.
return; return;
} }
const auto [tools_result, tools] = physical_device.getToolProperties(); const auto [tools_result, tools] = physical_device.getToolPropertiesEXT();
if (tools_result != vk::Result::eSuccess) { if (tools_result != vk::Result::eSuccess) {
LOG_ERROR(Render_Vulkan, "Could not get Vulkan tool properties: {}", LOG_ERROR(Render_Vulkan, "Could not get Vulkan tool properties: {}",
vk::to_string(tools_result)); vk::to_string(tools_result));

View file

@ -89,11 +89,6 @@ public:
return features.depthBounds; return features.depthBounds;
} }
/// Returns true if 64-bit floats are supported in shaders
bool IsShaderFloat64Supported() const {
return features.shaderFloat64;
}
/// Returns true when VK_EXT_custom_border_color is supported /// Returns true when VK_EXT_custom_border_color is supported
bool IsCustomBorderColorSupported() const { bool IsCustomBorderColorSupported() const {
return custom_border_color; return custom_border_color;
@ -316,7 +311,7 @@ private:
/// Collects telemetry information from the device. /// Collects telemetry information from the device.
void CollectDeviceParameters(); void CollectDeviceParameters();
void CollectToolingInfo() const; void CollectToolingInfo();
/// Gets the supported feature flags for a format. /// Gets the supported feature flags for a format.
[[nodiscard]] vk::FormatFeatureFlags2 GetFormatFeatureFlags(vk::Format format) const; [[nodiscard]] vk::FormatFeatureFlags2 GetFormatFeatureFlags(vk::Format format) const;

View file

@ -26,8 +26,6 @@ using Shader::LogicalStage;
using Shader::Stage; using Shader::Stage;
using Shader::VsOutput; using Shader::VsOutput;
constexpr static auto SpirvVersion1_6 = 0x00010600U;
constexpr static std::array DescriptorHeapSizes = { constexpr static std::array DescriptorHeapSizes = {
vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer, 8192}, vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer, 8192},
vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer, 1024}, vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer, 1024},
@ -194,9 +192,8 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} { desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} {
const auto& vk12_props = instance.GetVk12Properties(); const auto& vk12_props = instance.GetVk12Properties();
profile = Shader::Profile{ profile = Shader::Profile{
.supported_spirv = SpirvVersion1_6, .supported_spirv = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U,
.subgroup_size = instance.SubgroupSize(), .subgroup_size = instance.SubgroupSize(),
.support_float64 = instance.IsShaderFloat64Supported(),
.support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32), .support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32),
.support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32), .support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32),
.support_fp32_round_to_zero = bool(vk12_props.shaderRoundingModeRTZFloat32), .support_fp32_round_to_zero = bool(vk12_props.shaderRoundingModeRTZFloat32),

View file

@ -18,7 +18,7 @@ class WindowSDL;
namespace Vulkan { namespace Vulkan {
constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_3; constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_2;
vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window); vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window);

View file

@ -130,7 +130,7 @@ Presenter::Presenter(Frontend::WindowSDL& window_, AmdGpu::Liverpool* liverpool_
} }
fsr_pass.Create(device, instance.GetAllocator(), num_images); fsr_pass.Create(device, instance.GetAllocator(), num_images);
pp_pass.Create(device, swapchain.GetSurfaceFormat().format); pp_pass.Create(device);
ImGui::Layer::AddLayer(Common::Singleton<Core::Devtools::Layer>::Instance()); ImGui::Layer::AddLayer(Common::Singleton<Core::Devtools::Layer>::Instance());
} }

View file

@ -170,29 +170,29 @@ void Scheduler::SubmitExecution(SubmitInfo& info) {
void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf) { void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf) {
if (dirty_state.viewports) { if (dirty_state.viewports) {
dirty_state.viewports = false; dirty_state.viewports = false;
cmdbuf.setViewportWithCount(viewports); cmdbuf.setViewportWithCountEXT(viewports);
} }
if (dirty_state.scissors) { if (dirty_state.scissors) {
dirty_state.scissors = false; dirty_state.scissors = false;
cmdbuf.setScissorWithCount(scissors); cmdbuf.setScissorWithCountEXT(scissors);
} }
if (dirty_state.depth_test_enabled) { if (dirty_state.depth_test_enabled) {
dirty_state.depth_test_enabled = false; dirty_state.depth_test_enabled = false;
cmdbuf.setDepthTestEnable(depth_test_enabled); cmdbuf.setDepthTestEnableEXT(depth_test_enabled);
} }
if (dirty_state.depth_write_enabled) { if (dirty_state.depth_write_enabled) {
dirty_state.depth_write_enabled = false; dirty_state.depth_write_enabled = false;
// Note that this must be set in a command buffer even if depth test is disabled. // Note that this must be set in a command buffer even if depth test is disabled.
cmdbuf.setDepthWriteEnable(depth_write_enabled); cmdbuf.setDepthWriteEnableEXT(depth_write_enabled);
} }
if (depth_test_enabled && dirty_state.depth_compare_op) { if (depth_test_enabled && dirty_state.depth_compare_op) {
dirty_state.depth_compare_op = false; dirty_state.depth_compare_op = false;
cmdbuf.setDepthCompareOp(depth_compare_op); cmdbuf.setDepthCompareOpEXT(depth_compare_op);
} }
if (dirty_state.depth_bounds_test_enabled) { if (dirty_state.depth_bounds_test_enabled) {
dirty_state.depth_bounds_test_enabled = false; dirty_state.depth_bounds_test_enabled = false;
if (instance.IsDepthBoundsSupported()) { if (instance.IsDepthBoundsSupported()) {
cmdbuf.setDepthBoundsTestEnable(depth_bounds_test_enabled); cmdbuf.setDepthBoundsTestEnableEXT(depth_bounds_test_enabled);
} }
} }
if (depth_bounds_test_enabled && dirty_state.depth_bounds) { if (depth_bounds_test_enabled && dirty_state.depth_bounds) {
@ -203,7 +203,7 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
} }
if (dirty_state.depth_bias_enabled) { if (dirty_state.depth_bias_enabled) {
dirty_state.depth_bias_enabled = false; dirty_state.depth_bias_enabled = false;
cmdbuf.setDepthBiasEnable(depth_bias_enabled); cmdbuf.setDepthBiasEnableEXT(depth_bias_enabled);
} }
if (depth_bias_enabled && dirty_state.depth_bias) { if (depth_bias_enabled && dirty_state.depth_bias) {
dirty_state.depth_bias = false; dirty_state.depth_bias = false;
@ -211,26 +211,26 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
} }
if (dirty_state.stencil_test_enabled) { if (dirty_state.stencil_test_enabled) {
dirty_state.stencil_test_enabled = false; dirty_state.stencil_test_enabled = false;
cmdbuf.setStencilTestEnable(stencil_test_enabled); cmdbuf.setStencilTestEnableEXT(stencil_test_enabled);
} }
if (stencil_test_enabled) { if (stencil_test_enabled) {
if (dirty_state.stencil_front_ops && dirty_state.stencil_back_ops && if (dirty_state.stencil_front_ops && dirty_state.stencil_back_ops &&
stencil_front_ops == stencil_back_ops) { stencil_front_ops == stencil_back_ops) {
dirty_state.stencil_front_ops = false; dirty_state.stencil_front_ops = false;
dirty_state.stencil_back_ops = false; dirty_state.stencil_back_ops = false;
cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFrontAndBack, stencil_front_ops.fail_op, cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack,
stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, stencil_front_ops.fail_op, stencil_front_ops.pass_op,
stencil_front_ops.compare_op); stencil_front_ops.depth_fail_op, stencil_front_ops.compare_op);
} else { } else {
if (dirty_state.stencil_front_ops) { if (dirty_state.stencil_front_ops) {
dirty_state.stencil_front_ops = false; dirty_state.stencil_front_ops = false;
cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op, cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op,
stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op,
stencil_front_ops.compare_op); stencil_front_ops.compare_op);
} }
if (dirty_state.stencil_back_ops) { if (dirty_state.stencil_back_ops) {
dirty_state.stencil_back_ops = false; dirty_state.stencil_back_ops = false;
cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op, cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op,
stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op, stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op,
stencil_back_ops.compare_op); stencil_back_ops.compare_op);
} }
@ -291,16 +291,16 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
if (dirty_state.primitive_restart_enable) { if (dirty_state.primitive_restart_enable) {
dirty_state.primitive_restart_enable = false; dirty_state.primitive_restart_enable = false;
if (instance.IsPrimitiveRestartDisableSupported()) { if (instance.IsPrimitiveRestartDisableSupported()) {
cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable); cmdbuf.setPrimitiveRestartEnableEXT(primitive_restart_enable);
} }
} }
if (dirty_state.cull_mode) { if (dirty_state.cull_mode) {
dirty_state.cull_mode = false; dirty_state.cull_mode = false;
cmdbuf.setCullMode(cull_mode); cmdbuf.setCullModeEXT(cull_mode);
} }
if (dirty_state.front_face) { if (dirty_state.front_face) {
dirty_state.front_face = false; dirty_state.front_face = false;
cmdbuf.setFrontFace(front_face); cmdbuf.setFrontFaceEXT(front_face);
} }
if (dirty_state.blend_constants) { if (dirty_state.blend_constants) {
dirty_state.blend_constants = false; dirty_state.blend_constants = false;