diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9393380e2..55549ab4c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -205,8 +205,8 @@ jobs: run: | mkdir upload mv ${{github.workspace}}/build/shadps4 upload - cp ${{github.workspace}}/build/externals/MoltenVK/libMoltenVK.dylib upload - install_name_tool -add_rpath "@executable_path" upload/shadps4 + mv ${{github.workspace}}/build/MoltenVK_icd.json upload + mv ${{github.workspace}}/build/libMoltenVK.dylib upload - uses: actions/upload-artifact@v4 with: name: shadps4-macos-sdl-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }} diff --git a/.gitmodules b/.gitmodules index 9daefe305..065a4570f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -97,7 +97,7 @@ shallow = true [submodule "externals/MoltenVK/SPIRV-Cross"] path = externals/MoltenVK/SPIRV-Cross - url = https://github.com/billhollings/SPIRV-Cross + url = https://github.com/KhronosGroup/SPIRV-Cross shallow = true [submodule "externals/MoltenVK/MoltenVK"] path = externals/MoltenVK/MoltenVK diff --git a/CMakeLists.txt b/CMakeLists.txt index a7791dc7e..8d0e1935e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,7 +202,7 @@ execute_process( # Set Version set(EMULATOR_VERSION_MAJOR "0") -set(EMULATOR_VERSION_MINOR "7") +set(EMULATOR_VERSION_MINOR "8") set(EMULATOR_VERSION_PATCH "1") 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}") @@ -1087,34 +1087,45 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ENABLE_USERFAULTFD) endif() if (APPLE) - if (ENABLE_QT_GUI) - # Include MoltenVK in the app bundle, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers. - set(MVK_ICD ${CMAKE_CURRENT_SOURCE_DIR}/externals/MoltenVK/MoltenVK_icd.json) - target_sources(shadps4 PRIVATE ${MVK_ICD}) - set_source_files_properties(${MVK_ICD} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/vulkan/icd.d) + # 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) - set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib) - set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib) - add_custom_command( - OUTPUT ${MVK_DYLIB_DST} - DEPENDS ${MVK_DYLIB_SRC} - COMMAND cmake -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST}) - add_custom_target(CopyMoltenVK DEPENDS ${MVK_DYLIB_DST}) - add_dependencies(CopyMoltenVK MoltenVK) - add_dependencies(shadps4 CopyMoltenVK) - set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks") - else() - # For non-bundled SDL build, just do a normal library link. - target_link_libraries(shadps4 PRIVATE MoltenVK) - endif() + if (ENABLE_QT_GUI) + set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks") + set(MVK_ICD_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json) + set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib) + set(MVK_DYLIB_ICD_PATH "../../../Frameworks/libMoltenVK.dylib") + else() + set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path") + 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() - if (ARCHITECTURE STREQUAL "x86_64") - # Reserve system-managed memory space. - target_link_options(shadps4 PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x4000,-segaddr,TCB_SPACE,0x4000,-segaddr,SYSTEM_MANAGED,0x400000,-segaddr,SYSTEM_RESERVED,0x7FFFFC000,-image_base,0x20000000000) - endif() + cmake_path(GET MVK_ICD_DST PARENT_PATH MVK_ICD_DST_PARENT) + cmake_path(GET MVK_DYLIB_DST PARENT_PATH MVK_DYLIB_DST_PARENT) - # Replacement for std::chrono::time_zone - target_link_libraries(shadps4 PRIVATE date::date-tz) + 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 \\\} \\\}") + add_custom_command( + OUTPUT ${MVK_ICD_DST} + COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_ICD_DST_PARENT} && ${CMAKE_COMMAND} -E echo ${MVK_ICD} > ${MVK_ICD_DST}) + + add_custom_command( + OUTPUT ${MVK_DYLIB_DST} + DEPENDS ${MVK_DYLIB_SRC} + 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_dependencies(CopyMoltenVK MoltenVK) + add_dependencies(shadps4 CopyMoltenVK) + + if (ARCHITECTURE STREQUAL "x86_64") + # Reserve system-managed memory space. + target_link_options(shadps4 PRIVATE -Wl,-no_pie,-no_fixup_chains,-no_huge,-pagezero_size,0x4000,-segaddr,TCB_SPACE,0x4000,-segaddr,SYSTEM_MANAGED,0x400000,-segaddr,SYSTEM_RESERVED,0x7FFFFC000,-image_base,0x20000000000) + endif() + + # Replacement for std::chrono::time_zone + target_link_libraries(shadps4 PRIVATE date::date-tz) endif() if (NOT ENABLE_QT_GUI) diff --git a/dist/net.shadps4.shadPS4.metainfo.xml b/dist/net.shadps4.shadPS4.metainfo.xml index 99f9e070d..9f7b4f9c5 100644 --- a/dist/net.shadps4.shadPS4.metainfo.xml +++ b/dist/net.shadps4.shadPS4.metainfo.xml @@ -37,6 +37,9 @@ Game + + https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.8.0 + https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.7.0 diff --git a/externals/MoltenVK/MoltenVK b/externals/MoltenVK/MoltenVK index 067fc6c85..4cf8f9468 160000 --- a/externals/MoltenVK/MoltenVK +++ b/externals/MoltenVK/MoltenVK @@ -1 +1 @@ -Subproject commit 067fc6c85b02f37dfda58eeda49d8458e093ed60 +Subproject commit 4cf8f94684c53e581eb9cc694dd3305d1f7d9959 diff --git a/externals/MoltenVK/MoltenVK_icd.json b/externals/MoltenVK/MoltenVK_icd.json deleted file mode 100644 index 2c3319263..000000000 --- a/externals/MoltenVK/MoltenVK_icd.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "file_format_version": "1.0.0", - "ICD": { - "library_path": "../../../Frameworks/libMoltenVK.dylib", - "api_version": "1.2.0", - "is_portability_driver": true - } -} diff --git a/externals/MoltenVK/SPIRV-Cross b/externals/MoltenVK/SPIRV-Cross index 185833a61..2275d0efc 160000 --- a/externals/MoltenVK/SPIRV-Cross +++ b/externals/MoltenVK/SPIRV-Cross @@ -1 +1 @@ -Subproject commit 185833a61cbe29ce3bfb5a499ffb3dfeaee3bbe7 +Subproject commit 2275d0efc4f2fa46851035d9d3c67c105bc8b99e diff --git a/src/common/path_util.cpp b/src/common/path_util.cpp index 2ff1ddaf7..1a6ff9ec8 100644 --- a/src/common/path_util.cpp +++ b/src/common/path_util.cpp @@ -88,7 +88,7 @@ static std::optional GetBundleParentDirectory() { #endif static auto UserPaths = [] { -#ifdef __APPLE__ +#if defined(__APPLE__) && defined(ENABLE_QT_GUI) // Set the current path to the directory containing the app bundle. if (const auto bundle_dir = GetBundleParentDirectory()) { std::filesystem::current_path(*bundle_dir); diff --git a/src/qt_gui/kbm_gui.cpp b/src/qt_gui/kbm_gui.cpp index 2e1f6ddce..15e9008ab 100644 --- a/src/qt_gui/kbm_gui.cpp +++ b/src/qt_gui/kbm_gui.cpp @@ -608,21 +608,28 @@ void KBMSettings::CheckMapping(QPushButton*& button) { MappingTimer -= 1; 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) { EnableMapping = false; EnableMappingButtons(); 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) { @@ -647,322 +654,346 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) { } 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) { QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->isAutoRepeat()) + return true; + + if (pressedKeys.size() >= 3) { + return true; + } + switch (keyEvent->key()) { case Qt::Key_Space: - SetMapping("space"); + pressedKeys.insert("space"); break; case Qt::Key_Comma: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kpcomma"); + pressedKeys.insert("kpcomma"); } else { - SetMapping("comma"); + pressedKeys.insert("comma"); } break; case Qt::Key_Period: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kpperiod"); + pressedKeys.insert("kpperiod"); } else { - SetMapping("period"); + pressedKeys.insert("period"); } break; case Qt::Key_Slash: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) - SetMapping("kpdivide"); + pressedKeys.insert("kpdivide"); break; case Qt::Key_Asterisk: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) - SetMapping("kpmultiply"); + pressedKeys.insert("kpmultiply"); break; case Qt::Key_Question: - SetMapping("question"); + pressedKeys.insert("question"); break; case Qt::Key_Semicolon: - SetMapping("semicolon"); + pressedKeys.insert("semicolon"); break; case Qt::Key_Minus: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kpminus"); + pressedKeys.insert("kpminus"); } else { - SetMapping("minus"); + pressedKeys.insert("minus"); } break; case Qt::Key_Plus: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kpplus"); + pressedKeys.insert("kpplus"); } else { - SetMapping("plus"); + pressedKeys.insert("plus"); } break; case Qt::Key_ParenLeft: - SetMapping("lparenthesis"); + pressedKeys.insert("lparenthesis"); break; case Qt::Key_ParenRight: - SetMapping("rparenthesis"); + pressedKeys.insert("rparenthesis"); break; case Qt::Key_BracketLeft: - SetMapping("lbracket"); + pressedKeys.insert("lbracket"); break; case Qt::Key_BracketRight: - SetMapping("rbracket"); + pressedKeys.insert("rbracket"); break; case Qt::Key_BraceLeft: - SetMapping("lbrace"); + pressedKeys.insert("lbrace"); break; case Qt::Key_BraceRight: - SetMapping("rbrace"); + pressedKeys.insert("rbrace"); break; case Qt::Key_Backslash: - SetMapping("backslash"); + pressedKeys.insert("backslash"); break; case Qt::Key_Tab: - SetMapping("tab"); + pressedKeys.insert("tab"); break; case Qt::Key_Backspace: - SetMapping("backspace"); + pressedKeys.insert("backspace"); break; case Qt::Key_Return: - SetMapping("enter"); + pressedKeys.insert("enter"); break; case Qt::Key_Enter: - SetMapping("kpenter"); + pressedKeys.insert("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; case Qt::Key_Escape: - SetMapping("unmapped"); + pressedKeys.insert("unmapped"); break; case Qt::Key_Shift: - SetMapping("lshift"); + if (keyEvent->nativeScanCode() == rshift) { + pressedKeys.insert("rshift"); + } else { + pressedKeys.insert("lshift"); + } break; case Qt::Key_Alt: - SetMapping("lalt"); + if (keyEvent->nativeScanCode() == ralt) { + pressedKeys.insert("ralt"); + } else { + pressedKeys.insert("lalt"); + } break; case Qt::Key_Control: - SetMapping("lctrl"); + if (keyEvent->nativeScanCode() == rctrl) { + pressedKeys.insert("rctrl"); + } else { + pressedKeys.insert("lctrl"); + } break; case Qt::Key_Meta: activateWindow(); #ifdef _WIN32 - SetMapping("lwin"); + pressedKeys.insert("lwin"); #else - SetMapping("lmeta"); + pressedKeys.insert("lmeta"); #endif case Qt::Key_1: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp1"); + pressedKeys.insert("kp1"); } else { - SetMapping("1"); + pressedKeys.insert("1"); } break; case Qt::Key_2: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp2"); + pressedKeys.insert("kp2"); } else { - SetMapping("2"); + pressedKeys.insert("2"); } break; case Qt::Key_3: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp3"); + pressedKeys.insert("kp3"); } else { - SetMapping("3"); + pressedKeys.insert("3"); } break; case Qt::Key_4: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp4"); + pressedKeys.insert("kp4"); } else { - SetMapping("4"); + pressedKeys.insert("4"); } break; case Qt::Key_5: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp5"); + pressedKeys.insert("kp5"); } else { - SetMapping("5"); + pressedKeys.insert("5"); } break; case Qt::Key_6: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp6"); + pressedKeys.insert("kp6"); } else { - SetMapping("6"); + pressedKeys.insert("6"); } break; case Qt::Key_7: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp7"); + pressedKeys.insert("kp7"); } else { - SetMapping("7"); + pressedKeys.insert("7"); } break; case Qt::Key_8: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp8"); + pressedKeys.insert("kp8"); } else { - SetMapping("8"); + pressedKeys.insert("8"); } break; case Qt::Key_9: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp9"); + pressedKeys.insert("kp9"); } else { - SetMapping("9"); + pressedKeys.insert("9"); } break; case Qt::Key_0: if (Qt::KeypadModifier & QApplication::keyboardModifiers()) { - SetMapping("kp0"); + pressedKeys.insert("kp0"); } else { - SetMapping("0"); + pressedKeys.insert("0"); } break; case Qt::Key_Up: activateWindow(); - SetMapping("up"); + pressedKeys.insert("up"); break; case Qt::Key_Down: - SetMapping("down"); + pressedKeys.insert("down"); break; case Qt::Key_Left: - SetMapping("left"); + pressedKeys.insert("left"); break; case Qt::Key_Right: - SetMapping("right"); + pressedKeys.insert("right"); break; case Qt::Key_A: - SetMapping("a"); + pressedKeys.insert("a"); break; case Qt::Key_B: - SetMapping("b"); + pressedKeys.insert("b"); break; case Qt::Key_C: - SetMapping("c"); + pressedKeys.insert("c"); break; case Qt::Key_D: - SetMapping("d"); + pressedKeys.insert("d"); break; case Qt::Key_E: - SetMapping("e"); + pressedKeys.insert("e"); break; case Qt::Key_F: - SetMapping("f"); + pressedKeys.insert("f"); break; case Qt::Key_G: - SetMapping("g"); + pressedKeys.insert("g"); break; case Qt::Key_H: - SetMapping("h"); + pressedKeys.insert("h"); break; case Qt::Key_I: - SetMapping("i"); + pressedKeys.insert("i"); break; case Qt::Key_J: - SetMapping("j"); + pressedKeys.insert("j"); break; case Qt::Key_K: - SetMapping("k"); + pressedKeys.insert("k"); break; case Qt::Key_L: - SetMapping("l"); + pressedKeys.insert("l"); break; case Qt::Key_M: - SetMapping("m"); + pressedKeys.insert("m"); break; case Qt::Key_N: - SetMapping("n"); + pressedKeys.insert("n"); break; case Qt::Key_O: - SetMapping("o"); + pressedKeys.insert("o"); break; case Qt::Key_P: - SetMapping("p"); + pressedKeys.insert("p"); break; case Qt::Key_Q: - SetMapping("q"); + pressedKeys.insert("q"); break; case Qt::Key_R: - SetMapping("r"); + pressedKeys.insert("r"); break; case Qt::Key_S: - SetMapping("s"); + pressedKeys.insert("s"); break; case Qt::Key_T: - SetMapping("t"); + pressedKeys.insert("t"); break; case Qt::Key_U: - SetMapping("u"); + pressedKeys.insert("u"); break; case Qt::Key_V: - SetMapping("v"); + pressedKeys.insert("v"); break; case Qt::Key_W: - SetMapping("w"); + pressedKeys.insert("w"); break; case Qt::Key_X: - SetMapping("x"); + pressedKeys.insert("x"); break; case Qt::Key_Y: - SetMapping("Y"); + pressedKeys.insert("Y"); break; case Qt::Key_Z: - SetMapping("z"); + pressedKeys.insert("z"); break; default: break; } return true; } + } - if (event->type() == QEvent::MouseButtonPress) { - QMouseEvent* mouseEvent = static_cast(event); + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent* mouseEvent = static_cast(event); + if (pressedKeys.size() < 3) { switch (mouseEvent->button()) { case Qt::LeftButton: - SetMapping("leftbutton"); + pressedKeys.insert("leftbutton"); break; case Qt::RightButton: - SetMapping("rightbutton"); + pressedKeys.insert("rightbutton"); break; case Qt::MiddleButton: - SetMapping("middlebutton"); + pressedKeys.insert("middlebutton"); break; default: break; } return true; } + } - const QList AxisList = { - ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->LStickRightButton, - ui->RStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->RStickRightButton}; + const QList AxisList = { + ui->LStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->LStickRightButton, + ui->RStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->RStickRightButton}; - if (event->type() == QEvent::Wheel) { - QWheelEvent* wheelEvent = static_cast(event); + if (event->type() == QEvent::Wheel) { + QWheelEvent* wheelEvent = static_cast(event); + if (pressedKeys.size() < 3) { if (wheelEvent->angleDelta().y() > 5) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { - SetMapping("mousewheelup"); + pressedKeys.insert("mousewheelup"); } else { QMessageBox::information(this, tr("Cannot set mapping"), tr("Mousewheel cannot be mapped to stick outputs")); } } else if (wheelEvent->angleDelta().y() < -5) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { - SetMapping("mousewheeldown"); + pressedKeys.insert("mousewheeldown"); } else { QMessageBox::information(this, tr("Cannot set mapping"), tr("Mousewheel cannot be mapped to stick outputs")); @@ -972,9 +1003,9 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { // QT changes scrolling to horizontal for all widgets with the alt modifier if (Qt::AltModifier & QApplication::keyboardModifiers()) { - SetMapping("mousewheelup"); + pressedKeys.insert("mousewheelup"); } else { - SetMapping("mousewheelright"); + pressedKeys.insert("mousewheelright"); } } else { QMessageBox::information(this, tr("Cannot set mapping"), @@ -983,18 +1014,18 @@ bool KBMSettings::eventFilter(QObject* obj, QEvent* event) { } else if (wheelEvent->angleDelta().x() < -5) { if (std::find(AxisList.begin(), AxisList.end(), MappingButton) == AxisList.end()) { if (Qt::AltModifier & QApplication::keyboardModifiers()) { - SetMapping("mousewheeldown"); + pressedKeys.insert("mousewheeldown"); } else { - SetMapping("mousewheelleft"); + pressedKeys.insert("mousewheelleft"); } } else { QMessageBox::information(this, tr("Cannot set mapping"), tr("Mousewheel cannot be mapped to stick outputs")); } } - return true; } } + return QDialog::eventFilter(obj, event); } diff --git a/src/qt_gui/kbm_gui.h b/src/qt_gui/kbm_gui.h index 06e58eef6..bfeed2b01 100644 --- a/src/qt_gui/kbm_gui.h +++ b/src/qt_gui/kbm_gui.h @@ -25,6 +25,22 @@ private: std::unique_ptr ui; std::shared_ptr 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; void ButtonConnects(); void SetUIValuestoMappings(std::string config_id); @@ -33,6 +49,7 @@ private: void EnableMappingButtons(); void SetMapping(QString input); + QSet pressedKeys; bool EnableMapping = false; bool MappingCompleted = false; bool HelpWindowOpen = false; diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 036df24d8..936f82cd6 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -335,8 +335,7 @@ void DefineEntryPoint(const Info& info, EmitContext& ctx, Id main) { ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft); } if (info.has_discard) { - ctx.AddExtension("SPV_EXT_demote_to_helper_invocation"); - ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT); + ctx.AddCapability(spv::Capability::DemoteToHelperInvocation); } if (info.stores.GetAny(IR::Attribute::Depth)) { ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing); diff --git a/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp b/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp index c854e124f..0c40ffd7a 100644 --- a/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp +++ b/src/video_core/renderer_vulkan/host_passes/pp_pass.cpp @@ -78,7 +78,7 @@ void PostProcessingPass::Create(vk::Device device) { const std::array pp_color_formats{ vk::Format::eB8G8R8A8Unorm, // swapchain.GetSurfaceFormat().format, }; - const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci{ + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci{ .colorAttachmentCount = pp_color_formats.size(), .pColorAttachmentFormats = pp_color_formats.data(), }; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 354e22331..7c020a012 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -122,21 +122,21 @@ GraphicsPipeline::GraphicsPipeline( }; boost::container::static_vector dynamic_states = { - vk::DynamicState::eViewportWithCountEXT, vk::DynamicState::eScissorWithCountEXT, - vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnableEXT, - vk::DynamicState::eDepthWriteEnableEXT, vk::DynamicState::eDepthCompareOpEXT, - vk::DynamicState::eDepthBiasEnableEXT, vk::DynamicState::eDepthBias, - vk::DynamicState::eStencilTestEnableEXT, vk::DynamicState::eStencilReference, - vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, - vk::DynamicState::eStencilOpEXT, vk::DynamicState::eCullModeEXT, - vk::DynamicState::eFrontFaceEXT, + vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount, + vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable, + vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp, + vk::DynamicState::eDepthBiasEnable, vk::DynamicState::eDepthBias, + vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference, + vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, + vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode, + vk::DynamicState::eFrontFace, }; if (instance.IsPrimitiveRestartDisableSupported()) { - dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnableEXT); + dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnable); } if (instance.IsDepthBoundsSupported()) { - dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnableEXT); + dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnable); dynamic_states.push_back(vk::DynamicState::eDepthBounds); } if (instance.IsDynamicColorWriteMaskSupported()) { @@ -145,7 +145,7 @@ GraphicsPipeline::GraphicsPipeline( if (instance.IsVertexInputDynamicState()) { dynamic_states.push_back(vk::DynamicState::eVertexInputEXT); } else if (!vertex_bindings.empty()) { - dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStrideEXT); + dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride); } const vk::PipelineDynamicStateCreateInfo dynamic_info = { @@ -212,7 +212,7 @@ GraphicsPipeline::GraphicsPipeline( }); } - const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci = { + const vk::PipelineRenderingCreateInfo pipeline_rendering_ci = { .colorAttachmentCount = key.num_color_attachments, .pColorAttachmentFormats = key.color_formats.data(), .depthAttachmentFormat = key.depth_format, diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 0df020116..089c0f00d 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -203,12 +203,14 @@ std::string Instance::GetDriverVersionName() { } bool Instance::CreateDevice() { - const vk::StructureChain feature_chain = physical_device.getFeatures2< - vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features, - vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceRobustness2FeaturesEXT, - vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT, - vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT, - vk::PhysicalDevicePortabilitySubsetFeaturesKHR>(); + const vk::StructureChain feature_chain = + physical_device + .getFeatures2(); features = feature_chain.get().features; const vk::StructureChain properties_chain = physical_device.getProperties2< @@ -240,18 +242,6 @@ bool Instance::CreateDevice() { 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 ASSERT(add_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)); ASSERT(add_extension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME)); @@ -324,6 +314,7 @@ bool Instance::CreateDevice() { feature_chain.get(); const auto vk11_features = feature_chain.get(); const auto vk12_features = feature_chain.get(); + const auto vk13_features = feature_chain.get(); vk::StructureChain device_chain = { vk::DeviceCreateInfo{ .queueCreateInfoCount = 1u, @@ -372,26 +363,14 @@ bool Instance::CreateDevice() { .hostQueryReset = vk12_features.hostQueryReset, .timelineSemaphore = vk12_features.timelineSemaphore, }, - // Vulkan 1.3 promoted extensions - vk::PhysicalDeviceDynamicRenderingFeaturesKHR{ - .dynamicRendering = true, + vk::PhysicalDeviceVulkan13Features{ + .robustImageAccess = vk13_features.robustImageAccess, + .shaderDemoteToHelperInvocation = vk13_features.shaderDemoteToHelperInvocation, + .synchronization2 = vk13_features.synchronization2, + .dynamicRendering = vk13_features.dynamicRendering, + .maintenance4 = vk13_features.maintenance4, }, - vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT{ - .shaderDemoteToHelperInvocation = true, - }, - vk::PhysicalDeviceSynchronization2Features{ - .synchronization2 = true, - }, - vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT{ - .extendedDynamicState = true, - }, - vk::PhysicalDeviceExtendedDynamicState2FeaturesEXT{ - .extendedDynamicState2 = true, - }, - vk::PhysicalDeviceMaintenance4FeaturesKHR{ - .maintenance4 = true, - }, - // Other extensions + // Extensions vk::PhysicalDeviceCustomBorderColorFeaturesEXT{ .customBorderColors = true, .customBorderColorWithoutFormat = true, @@ -547,7 +526,7 @@ void Instance::CollectToolingInfo() { // Currently causes issues with Reshade on AMD proprietary, disabled until fix released. return; } - const auto [tools_result, tools] = physical_device.getToolPropertiesEXT(); + const auto [tools_result, tools] = physical_device.getToolProperties(); if (tools_result != vk::Result::eSuccess) { LOG_ERROR(Render_Vulkan, "Could not get Vulkan tool properties: {}", vk::to_string(tools_result)); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index bad2a549c..efb1966ba 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -26,6 +26,8 @@ using Shader::LogicalStage; using Shader::Stage; using Shader::VsOutput; +constexpr static auto SpirvVersion1_6 = 0x00010600U; + constexpr static std::array DescriptorHeapSizes = { vk::DescriptorPoolSize{vk::DescriptorType::eUniformBuffer, 8192}, vk::DescriptorPoolSize{vk::DescriptorType::eStorageBuffer, 1024}, @@ -192,7 +194,7 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, desc_heap{instance, scheduler.GetMasterSemaphore(), DescriptorHeapSizes} { const auto& vk12_props = instance.GetVk12Properties(); profile = Shader::Profile{ - .supported_spirv = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U, + .supported_spirv = SpirvVersion1_6, .subgroup_size = instance.SubgroupSize(), .support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32), .support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32), diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index e656369b2..c49e62f4e 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -22,6 +22,10 @@ #include "sdl_window.h" #include "video_core/renderer_vulkan/vk_platform.h" +#ifdef __APPLE__ +#include +#endif + namespace Vulkan { static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation"; @@ -223,8 +227,19 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e LOG_INFO(Render_Vulkan, "Creating vulkan instance"); #ifdef __APPLE__ +#ifndef ENABLE_QT_GUI + // Initialize the environment with the path to the MoltenVK ICD, so that the loader will + // find it. + static const auto icd_path = [] { + char path[PATH_MAX]; + u32 length = PATH_MAX; + _NSGetExecutablePath(path, &length); + return std::filesystem::path(path).parent_path() / "MoltenVK_icd.json"; + }(); + setenv("VK_DRIVER_FILES", icd_path.c_str(), true); +#endif // If the Vulkan loader exists in /usr/local/lib, give it priority. The Vulkan SDK - // installs it here by default but it is not in the default library search path. + // installs it here by default, but it is not in the default library search path. // The loader has a clause to check for it, but at a lower priority than the bundled // libMoltenVK.dylib, so we need to handle it ourselves to give it priority. static const std::string usr_local_path = "/usr/local/lib/libvulkan.dylib"; diff --git a/src/video_core/renderer_vulkan/vk_platform.h b/src/video_core/renderer_vulkan/vk_platform.h index 6a6ebeb15..b8f5f9f11 100644 --- a/src/video_core/renderer_vulkan/vk_platform.h +++ b/src/video_core/renderer_vulkan/vk_platform.h @@ -18,7 +18,7 @@ class WindowSDL; namespace Vulkan { -constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_2; +constexpr u32 TargetVulkanApiVersion = VK_API_VERSION_1_3; vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index a48d93dee..8d4188a22 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -170,29 +170,29 @@ void Scheduler::SubmitExecution(SubmitInfo& info) { void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmdbuf) { if (dirty_state.viewports) { dirty_state.viewports = false; - cmdbuf.setViewportWithCountEXT(viewports); + cmdbuf.setViewportWithCount(viewports); } if (dirty_state.scissors) { dirty_state.scissors = false; - cmdbuf.setScissorWithCountEXT(scissors); + cmdbuf.setScissorWithCount(scissors); } if (dirty_state.depth_test_enabled) { dirty_state.depth_test_enabled = false; - cmdbuf.setDepthTestEnableEXT(depth_test_enabled); + cmdbuf.setDepthTestEnable(depth_test_enabled); } if (dirty_state.depth_write_enabled) { dirty_state.depth_write_enabled = false; // Note that this must be set in a command buffer even if depth test is disabled. - cmdbuf.setDepthWriteEnableEXT(depth_write_enabled); + cmdbuf.setDepthWriteEnable(depth_write_enabled); } if (depth_test_enabled && dirty_state.depth_compare_op) { dirty_state.depth_compare_op = false; - cmdbuf.setDepthCompareOpEXT(depth_compare_op); + cmdbuf.setDepthCompareOp(depth_compare_op); } if (dirty_state.depth_bounds_test_enabled) { dirty_state.depth_bounds_test_enabled = false; if (instance.IsDepthBoundsSupported()) { - cmdbuf.setDepthBoundsTestEnableEXT(depth_bounds_test_enabled); + cmdbuf.setDepthBoundsTestEnable(depth_bounds_test_enabled); } } 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) { dirty_state.depth_bias_enabled = false; - cmdbuf.setDepthBiasEnableEXT(depth_bias_enabled); + cmdbuf.setDepthBiasEnable(depth_bias_enabled); } if (depth_bias_enabled && dirty_state.depth_bias) { dirty_state.depth_bias = false; @@ -211,28 +211,28 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd } if (dirty_state.stencil_test_enabled) { dirty_state.stencil_test_enabled = false; - cmdbuf.setStencilTestEnableEXT(stencil_test_enabled); + cmdbuf.setStencilTestEnable(stencil_test_enabled); } if (stencil_test_enabled) { if (dirty_state.stencil_front_ops && dirty_state.stencil_back_ops && stencil_front_ops == stencil_back_ops) { dirty_state.stencil_front_ops = false; dirty_state.stencil_back_ops = false; - cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack, - stencil_front_ops.fail_op, stencil_front_ops.pass_op, - stencil_front_ops.depth_fail_op, stencil_front_ops.compare_op); + cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFrontAndBack, stencil_front_ops.fail_op, + stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, + stencil_front_ops.compare_op); } else { if (dirty_state.stencil_front_ops) { dirty_state.stencil_front_ops = false; - cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op, - stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, - stencil_front_ops.compare_op); + cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_op, + stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op, + stencil_front_ops.compare_op); } if (dirty_state.stencil_back_ops) { dirty_state.stencil_back_ops = false; - cmdbuf.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op, - stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op, - stencil_back_ops.compare_op); + cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_op, + stencil_back_ops.pass_op, stencil_back_ops.depth_fail_op, + stencil_back_ops.compare_op); } } if (dirty_state.stencil_front_reference && dirty_state.stencil_back_reference && @@ -291,16 +291,16 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd if (dirty_state.primitive_restart_enable) { dirty_state.primitive_restart_enable = false; if (instance.IsPrimitiveRestartDisableSupported()) { - cmdbuf.setPrimitiveRestartEnableEXT(primitive_restart_enable); + cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable); } } if (dirty_state.cull_mode) { dirty_state.cull_mode = false; - cmdbuf.setCullModeEXT(cull_mode); + cmdbuf.setCullMode(cull_mode); } if (dirty_state.front_face) { dirty_state.front_face = false; - cmdbuf.setFrontFaceEXT(front_face); + cmdbuf.setFrontFace(front_face); } if (dirty_state.blend_constants) { dirty_state.blend_constants = false;