mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-14 08:12:16 +00:00
Merge branch 'shadps4-emu:main' into gnm-lle
This commit is contained in:
commit
38d24bc2f4
23 changed files with 362 additions and 252 deletions
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
|
@ -205,12 +205,12 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
mv ${{github.workspace}}/build/shadps4 upload
|
mv ${{github.workspace}}/build/shadps4 upload
|
||||||
cp ${{github.workspace}}/build/externals/MoltenVK/libMoltenVK.dylib upload
|
mv ${{github.workspace}}/build/MoltenVK_icd.json upload
|
||||||
tar cf shadps4-macos-sdl.tar.gz -C upload .
|
mv ${{github.workspace}}/build/libMoltenVK.dylib upload
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: shadps4-macos-sdl-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
|
name: shadps4-macos-sdl-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
|
||||||
path: shadps4-macos-sdl.tar.gz
|
path: upload/
|
||||||
|
|
||||||
macos-qt:
|
macos-qt:
|
||||||
runs-on: macos-15
|
runs-on: macos-15
|
||||||
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -97,7 +97,7 @@
|
||||||
shallow = true
|
shallow = true
|
||||||
[submodule "externals/MoltenVK/SPIRV-Cross"]
|
[submodule "externals/MoltenVK/SPIRV-Cross"]
|
||||||
path = 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
|
shallow = true
|
||||||
[submodule "externals/MoltenVK/MoltenVK"]
|
[submodule "externals/MoltenVK/MoltenVK"]
|
||||||
path = externals/MoltenVK/MoltenVK
|
path = externals/MoltenVK/MoltenVK
|
||||||
|
|
|
@ -202,7 +202,7 @@ execute_process(
|
||||||
|
|
||||||
# Set Version
|
# Set Version
|
||||||
set(EMULATOR_VERSION_MAJOR "0")
|
set(EMULATOR_VERSION_MAJOR "0")
|
||||||
set(EMULATOR_VERSION_MINOR "7")
|
set(EMULATOR_VERSION_MINOR "8")
|
||||||
set(EMULATOR_VERSION_PATCH "1")
|
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}")
|
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}")
|
||||||
|
@ -1085,34 +1085,45 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ENABLE_USERFAULTFD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
if (ENABLE_QT_GUI)
|
# Include MoltenVK, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers.
|
||||||
# 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_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
|
||||||
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)
|
|
||||||
|
|
||||||
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
|
if (ENABLE_QT_GUI)
|
||||||
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib)
|
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks")
|
||||||
add_custom_command(
|
set(MVK_ICD_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Resources/vulkan/icd.d/MoltenVK_icd.json)
|
||||||
OUTPUT ${MVK_DYLIB_DST}
|
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib)
|
||||||
DEPENDS ${MVK_DYLIB_SRC}
|
set(MVK_DYLIB_ICD_PATH "../../../Frameworks/libMoltenVK.dylib")
|
||||||
COMMAND cmake -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
|
else()
|
||||||
add_custom_target(CopyMoltenVK DEPENDS ${MVK_DYLIB_DST})
|
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path")
|
||||||
add_dependencies(CopyMoltenVK MoltenVK)
|
set(MVK_ICD_DST ${CMAKE_CURRENT_BINARY_DIR}/MoltenVK_icd.json)
|
||||||
add_dependencies(shadps4 CopyMoltenVK)
|
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/libMoltenVK.dylib)
|
||||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks")
|
set(MVK_DYLIB_ICD_PATH "./libMoltenVK.dylib")
|
||||||
else()
|
endif()
|
||||||
# For non-bundled SDL build, just do a normal library link.
|
|
||||||
target_link_libraries(shadps4 PRIVATE MoltenVK)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (ARCHITECTURE STREQUAL "x86_64")
|
cmake_path(GET MVK_ICD_DST PARENT_PATH MVK_ICD_DST_PARENT)
|
||||||
# Reserve system-managed memory space.
|
cmake_path(GET MVK_DYLIB_DST PARENT_PATH MVK_DYLIB_DST_PARENT)
|
||||||
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
|
set(MVK_ICD "\\\{ \\\"file_format_version\\\": \\\"1.0.0\\\", \\\"ICD\\\": \\\{ \\\"library_path\\\": \\\"${MVK_DYLIB_ICD_PATH}\\\", \\\"api_version\\\": \\\"1.3.0\\\", \\\"is_portability_driver\\\": true \\\} \\\}")
|
||||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
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()
|
endif()
|
||||||
|
|
||||||
if (NOT ENABLE_QT_GUI)
|
if (NOT ENABLE_QT_GUI)
|
||||||
|
|
3
dist/net.shadps4.shadPS4.metainfo.xml
vendored
3
dist/net.shadps4.shadPS4.metainfo.xml
vendored
|
@ -37,6 +37,9 @@
|
||||||
<category translate="no">Game</category>
|
<category translate="no">Game</category>
|
||||||
</categories>
|
</categories>
|
||||||
<releases>
|
<releases>
|
||||||
|
<release version="0.8.0" date="2025-05-23">
|
||||||
|
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.8.0</url>
|
||||||
|
</release>
|
||||||
<release version="0.7.0" date="2025-03-23">
|
<release version="0.7.0" date="2025-03-23">
|
||||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.7.0</url>
|
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.7.0</url>
|
||||||
</release>
|
</release>
|
||||||
|
|
2
externals/MoltenVK/MoltenVK
vendored
2
externals/MoltenVK/MoltenVK
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 067fc6c85b02f37dfda58eeda49d8458e093ed60
|
Subproject commit 4cf8f94684c53e581eb9cc694dd3305d1f7d9959
|
8
externals/MoltenVK/MoltenVK_icd.json
vendored
8
externals/MoltenVK/MoltenVK_icd.json
vendored
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
2
externals/MoltenVK/SPIRV-Cross
vendored
2
externals/MoltenVK/SPIRV-Cross
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 185833a61cbe29ce3bfb5a499ffb3dfeaee3bbe7
|
Subproject commit 2275d0efc4f2fa46851035d9d3c67c105bc8b99e
|
|
@ -60,7 +60,7 @@ static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::filesystem::path GetBundleParentDirectory() {
|
static std::optional<std::filesystem::path> GetBundleParentDirectory() {
|
||||||
if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) {
|
if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) {
|
||||||
if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) {
|
if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) {
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
|
@ -83,14 +83,16 @@ static std::filesystem::path GetBundleParentDirectory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::filesystem::current_path();
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static auto UserPaths = [] {
|
static auto UserPaths = [] {
|
||||||
#ifdef __APPLE__
|
#if defined(__APPLE__) && defined(ENABLE_QT_GUI)
|
||||||
// Set the current path to the directory containing the app bundle.
|
// Set the current path to the directory containing the app bundle.
|
||||||
std::filesystem::current_path(GetBundleParentDirectory());
|
if (const auto bundle_dir = GetBundleParentDirectory()) {
|
||||||
|
std::filesystem::current_path(*bundle_dir);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try the portable user directory first.
|
// Try the portable user directory first.
|
||||||
|
|
|
@ -608,21 +608,28 @@ 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" ||
|
button->setText(mapping);
|
||||||
mapping == "lwin") {
|
|
||||||
modifier = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifier != "") {
|
|
||||||
button->setText(modifier + ", " + mapping);
|
|
||||||
} else {
|
|
||||||
button->setText(mapping);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MappingTimer <= 0) {
|
if (MappingTimer <= 0) {
|
||||||
|
@ -647,322 +654,346 @@ 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:
|
||||||
SetMapping("space");
|
pressedKeys.insert("space");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Comma:
|
case Qt::Key_Comma:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kpcomma");
|
pressedKeys.insert("kpcomma");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("comma");
|
pressedKeys.insert("comma");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Period:
|
case Qt::Key_Period:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kpperiod");
|
pressedKeys.insert("kpperiod");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("period");
|
pressedKeys.insert("period");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Slash:
|
case Qt::Key_Slash:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
||||||
SetMapping("kpdivide");
|
pressedKeys.insert("kpdivide");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Asterisk:
|
case Qt::Key_Asterisk:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers())
|
||||||
SetMapping("kpmultiply");
|
pressedKeys.insert("kpmultiply");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Question:
|
case Qt::Key_Question:
|
||||||
SetMapping("question");
|
pressedKeys.insert("question");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Semicolon:
|
case Qt::Key_Semicolon:
|
||||||
SetMapping("semicolon");
|
pressedKeys.insert("semicolon");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Minus:
|
case Qt::Key_Minus:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kpminus");
|
pressedKeys.insert("kpminus");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("minus");
|
pressedKeys.insert("minus");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Plus:
|
case Qt::Key_Plus:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kpplus");
|
pressedKeys.insert("kpplus");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("plus");
|
pressedKeys.insert("plus");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_ParenLeft:
|
case Qt::Key_ParenLeft:
|
||||||
SetMapping("lparenthesis");
|
pressedKeys.insert("lparenthesis");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_ParenRight:
|
case Qt::Key_ParenRight:
|
||||||
SetMapping("rparenthesis");
|
pressedKeys.insert("rparenthesis");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_BracketLeft:
|
case Qt::Key_BracketLeft:
|
||||||
SetMapping("lbracket");
|
pressedKeys.insert("lbracket");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_BracketRight:
|
case Qt::Key_BracketRight:
|
||||||
SetMapping("rbracket");
|
pressedKeys.insert("rbracket");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_BraceLeft:
|
case Qt::Key_BraceLeft:
|
||||||
SetMapping("lbrace");
|
pressedKeys.insert("lbrace");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_BraceRight:
|
case Qt::Key_BraceRight:
|
||||||
SetMapping("rbrace");
|
pressedKeys.insert("rbrace");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Backslash:
|
case Qt::Key_Backslash:
|
||||||
SetMapping("backslash");
|
pressedKeys.insert("backslash");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Tab:
|
case Qt::Key_Tab:
|
||||||
SetMapping("tab");
|
pressedKeys.insert("tab");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Backspace:
|
case Qt::Key_Backspace:
|
||||||
SetMapping("backspace");
|
pressedKeys.insert("backspace");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Return:
|
case Qt::Key_Return:
|
||||||
SetMapping("enter");
|
pressedKeys.insert("enter");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Enter:
|
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;
|
break;
|
||||||
case Qt::Key_Escape:
|
case Qt::Key_Escape:
|
||||||
SetMapping("unmapped");
|
pressedKeys.insert("unmapped");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Shift:
|
case Qt::Key_Shift:
|
||||||
SetMapping("lshift");
|
if (keyEvent->nativeScanCode() == rshift) {
|
||||||
|
pressedKeys.insert("rshift");
|
||||||
|
} else {
|
||||||
|
pressedKeys.insert("lshift");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Alt:
|
case Qt::Key_Alt:
|
||||||
SetMapping("lalt");
|
if (keyEvent->nativeScanCode() == ralt) {
|
||||||
|
pressedKeys.insert("ralt");
|
||||||
|
} else {
|
||||||
|
pressedKeys.insert("lalt");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Control:
|
case Qt::Key_Control:
|
||||||
SetMapping("lctrl");
|
if (keyEvent->nativeScanCode() == rctrl) {
|
||||||
|
pressedKeys.insert("rctrl");
|
||||||
|
} else {
|
||||||
|
pressedKeys.insert("lctrl");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Meta:
|
case Qt::Key_Meta:
|
||||||
activateWindow();
|
activateWindow();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
SetMapping("lwin");
|
pressedKeys.insert("lwin");
|
||||||
#else
|
#else
|
||||||
SetMapping("lmeta");
|
pressedKeys.insert("lmeta");
|
||||||
#endif
|
#endif
|
||||||
case Qt::Key_1:
|
case Qt::Key_1:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp1");
|
pressedKeys.insert("kp1");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("1");
|
pressedKeys.insert("1");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_2:
|
case Qt::Key_2:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp2");
|
pressedKeys.insert("kp2");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("2");
|
pressedKeys.insert("2");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_3:
|
case Qt::Key_3:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp3");
|
pressedKeys.insert("kp3");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("3");
|
pressedKeys.insert("3");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_4:
|
case Qt::Key_4:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp4");
|
pressedKeys.insert("kp4");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("4");
|
pressedKeys.insert("4");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_5:
|
case Qt::Key_5:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp5");
|
pressedKeys.insert("kp5");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("5");
|
pressedKeys.insert("5");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_6:
|
case Qt::Key_6:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp6");
|
pressedKeys.insert("kp6");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("6");
|
pressedKeys.insert("6");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_7:
|
case Qt::Key_7:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp7");
|
pressedKeys.insert("kp7");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("7");
|
pressedKeys.insert("7");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_8:
|
case Qt::Key_8:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp8");
|
pressedKeys.insert("kp8");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("8");
|
pressedKeys.insert("8");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_9:
|
case Qt::Key_9:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp9");
|
pressedKeys.insert("kp9");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("9");
|
pressedKeys.insert("9");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_0:
|
case Qt::Key_0:
|
||||||
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
if (Qt::KeypadModifier & QApplication::keyboardModifiers()) {
|
||||||
SetMapping("kp0");
|
pressedKeys.insert("kp0");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("0");
|
pressedKeys.insert("0");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Up:
|
case Qt::Key_Up:
|
||||||
activateWindow();
|
activateWindow();
|
||||||
SetMapping("up");
|
pressedKeys.insert("up");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Down:
|
case Qt::Key_Down:
|
||||||
SetMapping("down");
|
pressedKeys.insert("down");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
SetMapping("left");
|
pressedKeys.insert("left");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Right:
|
case Qt::Key_Right:
|
||||||
SetMapping("right");
|
pressedKeys.insert("right");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_A:
|
case Qt::Key_A:
|
||||||
SetMapping("a");
|
pressedKeys.insert("a");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_B:
|
case Qt::Key_B:
|
||||||
SetMapping("b");
|
pressedKeys.insert("b");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_C:
|
case Qt::Key_C:
|
||||||
SetMapping("c");
|
pressedKeys.insert("c");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_D:
|
case Qt::Key_D:
|
||||||
SetMapping("d");
|
pressedKeys.insert("d");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_E:
|
case Qt::Key_E:
|
||||||
SetMapping("e");
|
pressedKeys.insert("e");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_F:
|
case Qt::Key_F:
|
||||||
SetMapping("f");
|
pressedKeys.insert("f");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_G:
|
case Qt::Key_G:
|
||||||
SetMapping("g");
|
pressedKeys.insert("g");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_H:
|
case Qt::Key_H:
|
||||||
SetMapping("h");
|
pressedKeys.insert("h");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_I:
|
case Qt::Key_I:
|
||||||
SetMapping("i");
|
pressedKeys.insert("i");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_J:
|
case Qt::Key_J:
|
||||||
SetMapping("j");
|
pressedKeys.insert("j");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_K:
|
case Qt::Key_K:
|
||||||
SetMapping("k");
|
pressedKeys.insert("k");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_L:
|
case Qt::Key_L:
|
||||||
SetMapping("l");
|
pressedKeys.insert("l");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_M:
|
case Qt::Key_M:
|
||||||
SetMapping("m");
|
pressedKeys.insert("m");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_N:
|
case Qt::Key_N:
|
||||||
SetMapping("n");
|
pressedKeys.insert("n");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_O:
|
case Qt::Key_O:
|
||||||
SetMapping("o");
|
pressedKeys.insert("o");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_P:
|
case Qt::Key_P:
|
||||||
SetMapping("p");
|
pressedKeys.insert("p");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Q:
|
case Qt::Key_Q:
|
||||||
SetMapping("q");
|
pressedKeys.insert("q");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_R:
|
case Qt::Key_R:
|
||||||
SetMapping("r");
|
pressedKeys.insert("r");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_S:
|
case Qt::Key_S:
|
||||||
SetMapping("s");
|
pressedKeys.insert("s");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_T:
|
case Qt::Key_T:
|
||||||
SetMapping("t");
|
pressedKeys.insert("t");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_U:
|
case Qt::Key_U:
|
||||||
SetMapping("u");
|
pressedKeys.insert("u");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_V:
|
case Qt::Key_V:
|
||||||
SetMapping("v");
|
pressedKeys.insert("v");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_W:
|
case Qt::Key_W:
|
||||||
SetMapping("w");
|
pressedKeys.insert("w");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_X:
|
case Qt::Key_X:
|
||||||
SetMapping("x");
|
pressedKeys.insert("x");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Y:
|
case Qt::Key_Y:
|
||||||
SetMapping("Y");
|
pressedKeys.insert("Y");
|
||||||
break;
|
break;
|
||||||
case Qt::Key_Z:
|
case Qt::Key_Z:
|
||||||
SetMapping("z");
|
pressedKeys.insert("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:
|
||||||
SetMapping("leftbutton");
|
pressedKeys.insert("leftbutton");
|
||||||
break;
|
break;
|
||||||
case Qt::RightButton:
|
case Qt::RightButton:
|
||||||
SetMapping("rightbutton");
|
pressedKeys.insert("rightbutton");
|
||||||
break;
|
break;
|
||||||
case Qt::MiddleButton:
|
case Qt::MiddleButton:
|
||||||
SetMapping("middlebutton");
|
pressedKeys.insert("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,
|
||||||
ui->RStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->RStickRightButton};
|
ui->RStickUpButton, ui->LStickDownButton, ui->LStickLeftButton, ui->RStickRightButton};
|
||||||
|
|
||||||
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()) {
|
||||||
SetMapping("mousewheelup");
|
pressedKeys.insert("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()) {
|
||||||
SetMapping("mousewheeldown");
|
pressedKeys.insert("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"));
|
||||||
|
@ -972,9 +1003,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()) {
|
||||||
SetMapping("mousewheelup");
|
pressedKeys.insert("mousewheelup");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("mousewheelright");
|
pressedKeys.insert("mousewheelright");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::information(this, tr("Cannot set mapping"),
|
QMessageBox::information(this, tr("Cannot set mapping"),
|
||||||
|
@ -983,18 +1014,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()) {
|
||||||
SetMapping("mousewheeldown");
|
pressedKeys.insert("mousewheeldown");
|
||||||
} else {
|
} else {
|
||||||
SetMapping("mousewheelleft");
|
pressedKeys.insert("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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,22 @@ 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);
|
||||||
|
@ -33,6 +49,7 @@ 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;
|
||||||
|
|
|
@ -335,8 +335,7 @@ 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.AddExtension("SPV_EXT_demote_to_helper_invocation");
|
ctx.AddCapability(spv::Capability::DemoteToHelperInvocation);
|
||||||
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);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "shader_recompiler/frontend/control_flow_graph.h"
|
#include "shader_recompiler/frontend/control_flow_graph.h"
|
||||||
|
|
||||||
namespace Shader::Gcn {
|
namespace Shader::Gcn {
|
||||||
|
@ -67,6 +68,39 @@ static bool IgnoresExecMask(const GcnInst& inst) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::optional<u32> ResolveSetPcTarget(std::span<const GcnInst> list, u32 setpc_index,
|
||||||
|
std::span<const u32> pc_map) {
|
||||||
|
if (setpc_index < 3) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& getpc = list[setpc_index - 3];
|
||||||
|
const auto& arith = list[setpc_index - 2];
|
||||||
|
const auto& setpc = list[setpc_index];
|
||||||
|
|
||||||
|
if (getpc.opcode != Opcode::S_GETPC_B64 ||
|
||||||
|
!(arith.opcode == Opcode::S_ADD_U32 || arith.opcode == Opcode::S_SUB_U32) ||
|
||||||
|
setpc.opcode != Opcode::S_SETPC_B64)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
if (getpc.dst[0].code != setpc.src[0].code || arith.dst[0].code != setpc.src[0].code)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
if (arith.src_count < 2 || arith.src[1].field != OperandField::LiteralConst)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
const u32 imm = arith.src[1].code;
|
||||||
|
|
||||||
|
const s32 signed_offset =
|
||||||
|
(arith.opcode == Opcode::S_ADD_U32) ? static_cast<s32>(imm) : -static_cast<s32>(imm);
|
||||||
|
|
||||||
|
const u32 base_pc = pc_map[setpc_index - 3] + getpc.length;
|
||||||
|
|
||||||
|
const u32 result_pc = static_cast<u32>(static_cast<s32>(base_pc) + signed_offset);
|
||||||
|
LOG_DEBUG(Render_Recompiler, "SetPC target: {} + {} = {}", base_pc, signed_offset, result_pc);
|
||||||
|
return result_pc & ~0x3u;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr size_t LabelReserveSize = 32;
|
static constexpr size_t LabelReserveSize = 32;
|
||||||
|
|
||||||
CFG::CFG(Common::ObjectPool<Block>& block_pool_, std::span<const GcnInst> inst_list_)
|
CFG::CFG(Common::ObjectPool<Block>& block_pool_, std::span<const GcnInst> inst_list_)
|
||||||
|
@ -89,9 +123,20 @@ void CFG::EmitLabels() {
|
||||||
index_to_pc[i] = pc;
|
index_to_pc[i] = pc;
|
||||||
const GcnInst inst = inst_list[i];
|
const GcnInst inst = inst_list[i];
|
||||||
if (inst.IsUnconditionalBranch()) {
|
if (inst.IsUnconditionalBranch()) {
|
||||||
const u32 target = inst.BranchTarget(pc);
|
u32 target = inst.BranchTarget(pc);
|
||||||
|
if (inst.opcode == Opcode::S_SETPC_B64) {
|
||||||
|
if (auto t = ResolveSetPcTarget(inst_list, i, index_to_pc)) {
|
||||||
|
target = *t;
|
||||||
|
} else {
|
||||||
|
ASSERT_MSG(
|
||||||
|
false,
|
||||||
|
"S_SETPC_B64 without a resolvable offset at PC {:#x} (Index {}): Involved "
|
||||||
|
"instructions not recognized or invalid pattern",
|
||||||
|
pc, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
AddLabel(target);
|
AddLabel(target);
|
||||||
// Emit this label so that the block ends with s_branch instruction
|
// Emit this label so that the block ends with the branching instruction
|
||||||
AddLabel(pc + inst.length);
|
AddLabel(pc + inst.length);
|
||||||
} else if (inst.IsConditionalBranch()) {
|
} else if (inst.IsConditionalBranch()) {
|
||||||
const u32 true_label = inst.BranchTarget(pc);
|
const u32 true_label = inst.BranchTarget(pc);
|
||||||
|
@ -102,6 +147,7 @@ void CFG::EmitLabels() {
|
||||||
const u32 next_label = pc + inst.length;
|
const u32 next_label = pc + inst.length;
|
||||||
AddLabel(next_label);
|
AddLabel(next_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
pc += inst.length;
|
pc += inst.length;
|
||||||
}
|
}
|
||||||
index_to_pc[inst_list.size()] = pc;
|
index_to_pc[inst_list.size()] = pc;
|
||||||
|
@ -280,7 +326,18 @@ void CFG::LinkBlocks() {
|
||||||
// Find the branch targets from the instruction and link the blocks.
|
// Find the branch targets from the instruction and link the blocks.
|
||||||
// Note: Block end address is one instruction after end_inst.
|
// Note: Block end address is one instruction after end_inst.
|
||||||
const u32 branch_pc = block.end - end_inst.length;
|
const u32 branch_pc = block.end - end_inst.length;
|
||||||
const u32 target_pc = end_inst.BranchTarget(branch_pc);
|
u32 target_pc = 0;
|
||||||
|
if (end_inst.opcode == Opcode::S_SETPC_B64) {
|
||||||
|
auto tgt = ResolveSetPcTarget(inst_list, block.end_index, index_to_pc);
|
||||||
|
ASSERT_MSG(tgt,
|
||||||
|
"S_SETPC_B64 without a resolvable offset at PC {:#x} (Index {}): Involved "
|
||||||
|
"instructions not recognized or invalid pattern",
|
||||||
|
branch_pc, block.end_index);
|
||||||
|
target_pc = *tgt;
|
||||||
|
} else {
|
||||||
|
target_pc = end_inst.BranchTarget(branch_pc);
|
||||||
|
}
|
||||||
|
|
||||||
if (end_inst.IsUnconditionalBranch()) {
|
if (end_inst.IsUnconditionalBranch()) {
|
||||||
auto* target_block = get_block(target_pc);
|
auto* target_block = get_block(target_pc);
|
||||||
++target_block->num_predecessors;
|
++target_block->num_predecessors;
|
||||||
|
|
|
@ -18,7 +18,7 @@ bool GcnInst::IsTerminateInstruction() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcnInst::IsUnconditionalBranch() const {
|
bool GcnInst::IsUnconditionalBranch() const {
|
||||||
return opcode == Opcode::S_BRANCH;
|
return opcode == Opcode::S_BRANCH || opcode == Opcode::S_SETPC_B64;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcnInst::IsFork() const {
|
bool GcnInst::IsFork() const {
|
||||||
|
|
|
@ -18,6 +18,7 @@ void Translator::EmitFlowControl(u32 pc, const GcnInst& inst) {
|
||||||
return;
|
return;
|
||||||
case Opcode::S_GETPC_B64:
|
case Opcode::S_GETPC_B64:
|
||||||
return S_GETPC_B64(pc, inst);
|
return S_GETPC_B64(pc, inst);
|
||||||
|
case Opcode::S_SETPC_B64:
|
||||||
case Opcode::S_WAITCNT:
|
case Opcode::S_WAITCNT:
|
||||||
case Opcode::S_NOP:
|
case Opcode::S_NOP:
|
||||||
case Opcode::S_ENDPGM:
|
case Opcode::S_ENDPGM:
|
||||||
|
|
|
@ -78,7 +78,7 @@ void PostProcessingPass::Create(vk::Device device) {
|
||||||
const std::array pp_color_formats{
|
const std::array pp_color_formats{
|
||||||
vk::Format::eB8G8R8A8Unorm, // swapchain.GetSurfaceFormat().format,
|
vk::Format::eB8G8R8A8Unorm, // swapchain.GetSurfaceFormat().format,
|
||||||
};
|
};
|
||||||
const vk::PipelineRenderingCreateInfoKHR pipeline_rendering_ci{
|
const vk::PipelineRenderingCreateInfo pipeline_rendering_ci{
|
||||||
.colorAttachmentCount = pp_color_formats.size(),
|
.colorAttachmentCount = pp_color_formats.size(),
|
||||||
.pColorAttachmentFormats = pp_color_formats.data(),
|
.pColorAttachmentFormats = pp_color_formats.data(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -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::eViewportWithCountEXT, vk::DynamicState::eScissorWithCountEXT,
|
vk::DynamicState::eViewportWithCount, vk::DynamicState::eScissorWithCount,
|
||||||
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnableEXT,
|
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnable,
|
||||||
vk::DynamicState::eDepthWriteEnableEXT, vk::DynamicState::eDepthCompareOpEXT,
|
vk::DynamicState::eDepthWriteEnable, vk::DynamicState::eDepthCompareOp,
|
||||||
vk::DynamicState::eDepthBiasEnableEXT, vk::DynamicState::eDepthBias,
|
vk::DynamicState::eDepthBiasEnable, vk::DynamicState::eDepthBias,
|
||||||
vk::DynamicState::eStencilTestEnableEXT, vk::DynamicState::eStencilReference,
|
vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference,
|
||||||
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
|
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
|
||||||
vk::DynamicState::eStencilOpEXT, vk::DynamicState::eCullModeEXT,
|
vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode,
|
||||||
vk::DynamicState::eFrontFaceEXT,
|
vk::DynamicState::eFrontFace,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (instance.IsPrimitiveRestartDisableSupported()) {
|
if (instance.IsPrimitiveRestartDisableSupported()) {
|
||||||
dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnableEXT);
|
dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnable);
|
||||||
}
|
}
|
||||||
if (instance.IsDepthBoundsSupported()) {
|
if (instance.IsDepthBoundsSupported()) {
|
||||||
dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnableEXT);
|
dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnable);
|
||||||
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::eVertexInputBindingStrideEXT);
|
dynamic_states.push_back(vk::DynamicState::eVertexInputBindingStride);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
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,
|
.colorAttachmentCount = key.num_color_attachments,
|
||||||
.pColorAttachmentFormats = key.color_formats.data(),
|
.pColorAttachmentFormats = key.color_formats.data(),
|
||||||
.depthAttachmentFormat = key.depth_format,
|
.depthAttachmentFormat = key.depth_format,
|
||||||
|
|
|
@ -203,12 +203,14 @@ std::string Instance::GetDriverVersionName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Instance::CreateDevice() {
|
bool Instance::CreateDevice() {
|
||||||
const vk::StructureChain feature_chain = physical_device.getFeatures2<
|
const vk::StructureChain feature_chain =
|
||||||
vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features,
|
physical_device
|
||||||
vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceRobustness2FeaturesEXT,
|
.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan11Features,
|
||||||
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT,
|
vk::PhysicalDeviceVulkan12Features, vk::PhysicalDeviceVulkan13Features,
|
||||||
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
|
vk::PhysicalDeviceRobustness2FeaturesEXT,
|
||||||
vk::PhysicalDevicePortabilitySubsetFeaturesKHR>();
|
vk::PhysicalDeviceExtendedDynamicState3FeaturesEXT,
|
||||||
|
vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT,
|
||||||
|
vk::PhysicalDevicePortabilitySubsetFeaturesKHR>();
|
||||||
features = feature_chain.get().features;
|
features = feature_chain.get().features;
|
||||||
|
|
||||||
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
const vk::StructureChain properties_chain = physical_device.getProperties2<
|
||||||
|
@ -240,18 +242,6 @@ 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));
|
||||||
|
@ -324,6 +314,7 @@ 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,
|
||||||
|
@ -372,26 +363,14 @@ bool Instance::CreateDevice() {
|
||||||
.hostQueryReset = vk12_features.hostQueryReset,
|
.hostQueryReset = vk12_features.hostQueryReset,
|
||||||
.timelineSemaphore = vk12_features.timelineSemaphore,
|
.timelineSemaphore = vk12_features.timelineSemaphore,
|
||||||
},
|
},
|
||||||
// Vulkan 1.3 promoted extensions
|
vk::PhysicalDeviceVulkan13Features{
|
||||||
vk::PhysicalDeviceDynamicRenderingFeaturesKHR{
|
.robustImageAccess = vk13_features.robustImageAccess,
|
||||||
.dynamicRendering = true,
|
.shaderDemoteToHelperInvocation = vk13_features.shaderDemoteToHelperInvocation,
|
||||||
|
.synchronization2 = vk13_features.synchronization2,
|
||||||
|
.dynamicRendering = vk13_features.dynamicRendering,
|
||||||
|
.maintenance4 = vk13_features.maintenance4,
|
||||||
},
|
},
|
||||||
vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT{
|
// Extensions
|
||||||
.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,
|
||||||
|
@ -542,12 +521,14 @@ void Instance::CollectDeviceParameters() {
|
||||||
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions);
|
LOG_INFO(Render_Vulkan, "GPU_Vulkan_Extensions: {}", extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::CollectToolingInfo() {
|
void Instance::CollectToolingInfo() const {
|
||||||
if (GetDriverID() == vk::DriverId::eAmdProprietary) {
|
if (driver_id == vk::DriverId::eAmdProprietary ||
|
||||||
// Currently causes issues with Reshade on AMD proprietary, disabled until fix released.
|
driver_id == vk::DriverId::eIntelProprietaryWindows) {
|
||||||
|
// AMD: Causes issues with Reshade.
|
||||||
|
// Intel: Causes crash on start.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto [tools_result, tools] = physical_device.getToolPropertiesEXT();
|
const auto [tools_result, tools] = physical_device.getToolProperties();
|
||||||
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));
|
||||||
|
|
|
@ -311,7 +311,7 @@ private:
|
||||||
|
|
||||||
/// Collects telemetry information from the device.
|
/// Collects telemetry information from the device.
|
||||||
void CollectDeviceParameters();
|
void CollectDeviceParameters();
|
||||||
void CollectToolingInfo();
|
void CollectToolingInfo() const;
|
||||||
|
|
||||||
/// 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;
|
||||||
|
|
|
@ -26,6 +26,8 @@ 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},
|
||||||
|
@ -192,7 +194,7 @@ 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 = instance.ApiVersion() >= VK_API_VERSION_1_3 ? 0x00010600U : 0x00010500U,
|
.supported_spirv = SpirvVersion1_6,
|
||||||
.subgroup_size = instance.SubgroupSize(),
|
.subgroup_size = instance.SubgroupSize(),
|
||||||
.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),
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include "sdl_window.h"
|
#include "sdl_window.h"
|
||||||
#include "video_core/renderer_vulkan/vk_platform.h"
|
#include "video_core/renderer_vulkan/vk_platform.h"
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach-o/dyld.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
static const char* const VALIDATION_LAYER_NAME = "VK_LAYER_KHRONOS_validation";
|
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");
|
LOG_INFO(Render_Vulkan, "Creating vulkan instance");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#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
|
// 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
|
// 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.
|
// 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";
|
static const std::string usr_local_path = "/usr/local/lib/libvulkan.dylib";
|
||||||
|
|
|
@ -18,7 +18,7 @@ class WindowSDL;
|
||||||
|
|
||||||
namespace Vulkan {
|
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);
|
vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window);
|
||||||
|
|
||||||
|
|
|
@ -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.setViewportWithCountEXT(viewports);
|
cmdbuf.setViewportWithCount(viewports);
|
||||||
}
|
}
|
||||||
if (dirty_state.scissors) {
|
if (dirty_state.scissors) {
|
||||||
dirty_state.scissors = false;
|
dirty_state.scissors = false;
|
||||||
cmdbuf.setScissorWithCountEXT(scissors);
|
cmdbuf.setScissorWithCount(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.setDepthTestEnableEXT(depth_test_enabled);
|
cmdbuf.setDepthTestEnable(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.setDepthWriteEnableEXT(depth_write_enabled);
|
cmdbuf.setDepthWriteEnable(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.setDepthCompareOpEXT(depth_compare_op);
|
cmdbuf.setDepthCompareOp(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.setDepthBoundsTestEnableEXT(depth_bounds_test_enabled);
|
cmdbuf.setDepthBoundsTestEnable(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.setDepthBiasEnableEXT(depth_bias_enabled);
|
cmdbuf.setDepthBiasEnable(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,28 +211,28 @@ 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.setStencilTestEnableEXT(stencil_test_enabled);
|
cmdbuf.setStencilTestEnable(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.setStencilOpEXT(vk::StencilFaceFlagBits::eFrontAndBack,
|
cmdbuf.setStencilOp(vk::StencilFaceFlagBits::eFrontAndBack, stencil_front_ops.fail_op,
|
||||||
stencil_front_ops.fail_op, stencil_front_ops.pass_op,
|
stencil_front_ops.pass_op, stencil_front_ops.depth_fail_op,
|
||||||
stencil_front_ops.depth_fail_op, stencil_front_ops.compare_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.setStencilOpEXT(vk::StencilFaceFlagBits::eFront, stencil_front_ops.fail_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.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.setStencilOpEXT(vk::StencilFaceFlagBits::eBack, stencil_back_ops.fail_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.pass_op, stencil_back_ops.depth_fail_op,
|
||||||
stencil_back_ops.compare_op);
|
stencil_back_ops.compare_op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dirty_state.stencil_front_reference && dirty_state.stencil_back_reference &&
|
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) {
|
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.setPrimitiveRestartEnableEXT(primitive_restart_enable);
|
cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dirty_state.cull_mode) {
|
if (dirty_state.cull_mode) {
|
||||||
dirty_state.cull_mode = false;
|
dirty_state.cull_mode = false;
|
||||||
cmdbuf.setCullModeEXT(cull_mode);
|
cmdbuf.setCullMode(cull_mode);
|
||||||
}
|
}
|
||||||
if (dirty_state.front_face) {
|
if (dirty_state.front_face) {
|
||||||
dirty_state.front_face = false;
|
dirty_state.front_face = false;
|
||||||
cmdbuf.setFrontFaceEXT(front_face);
|
cmdbuf.setFrontFace(front_face);
|
||||||
}
|
}
|
||||||
if (dirty_state.blend_constants) {
|
if (dirty_state.blend_constants) {
|
||||||
dirty_state.blend_constants = false;
|
dirty_state.blend_constants = false;
|
||||||
|
|
|
@ -319,15 +319,14 @@ ImageId TextureCache::FindImage(BaseDesc& desc, FindFlags flags) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (False(flags & FindFlags::RelaxFmt) &&
|
if (False(flags & FindFlags::RelaxFmt) &&
|
||||||
!IsVulkanFormatCompatible(info.pixel_format, cache_image.info.pixel_format)) {
|
(!IsVulkanFormatCompatible(info.pixel_format, cache_image.info.pixel_format) ||
|
||||||
|
(cache_image.info.type != info.type && info.size != Extent3D{1, 1, 1}))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (True(flags & FindFlags::ExactFmt) &&
|
if (True(flags & FindFlags::ExactFmt) &&
|
||||||
info.pixel_format != cache_image.info.pixel_format) {
|
info.pixel_format != cache_image.info.pixel_format) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ASSERT((cache_image.info.type == info.type || info.size == Extent3D{1, 1, 1} ||
|
|
||||||
True(flags & FindFlags::RelaxFmt)));
|
|
||||||
image_id = cache_id;
|
image_id = cache_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue