diff --git a/externals/date b/externals/date index 51ce7e131..dd8affc6d 160000 --- a/externals/date +++ b/externals/date @@ -1 +1 @@ -Subproject commit 51ce7e131079c061533d741be5fe7cca57f2faac +Subproject commit dd8affc6de5755e07638bf0a14382d29549d6ee9 diff --git a/externals/sdl3 b/externals/sdl3 index 0548050fc..54e622c2e 160000 --- a/externals/sdl3 +++ b/externals/sdl3 @@ -1 +1 @@ -Subproject commit 0548050fc5a4edf1f47c3633c2cd06d8762b5532 +Subproject commit 54e622c2e6af456bfef382fae44c17682d5ac88a diff --git a/externals/sirit b/externals/sirit index 37090c74c..6cecb95d6 160000 --- a/externals/sirit +++ b/externals/sirit @@ -1 +1 @@ -Subproject commit 37090c74cc6e680f2bc334cac8fd182f7634a1f6 +Subproject commit 6cecb95d679c82c413d1f989e0b7ad9af130600d diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp index 894f5da55..7fed42a44 100644 --- a/src/audio_core/sdl_audio.cpp +++ b/src/audio_core/sdl_audio.cpp @@ -103,7 +103,7 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { const size_t data_size = port.samples_num * port.sample_size * port.channels_num; - SDL_bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); + bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); lock.unlock(); // Unlock only after necessary operations diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 2c03dde3e..35d5851ea 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -18,6 +18,8 @@ namespace Libraries::Net { +static thread_local int32_t net_errno = 0; + int PS4_SYSV_ABI in6addr_any() { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; @@ -563,9 +565,9 @@ int PS4_SYSV_ABI sceNetEpollWait() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetErrnoLoc() { +int* PS4_SYSV_ABI sceNetErrnoLoc() { LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; + return &net_errno; } int PS4_SYSV_ABI sceNetEtherNtostr() { diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index eababdb67..3f010f685 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -136,7 +136,7 @@ int PS4_SYSV_ABI sceNetEpollControl(); int PS4_SYSV_ABI sceNetEpollCreate(); int PS4_SYSV_ABI sceNetEpollDestroy(); int PS4_SYSV_ABI sceNetEpollWait(); -int PS4_SYSV_ABI sceNetErrnoLoc(); +int* PS4_SYSV_ABI sceNetErrnoLoc(); int PS4_SYSV_ABI sceNetEtherNtostr(); int PS4_SYSV_ABI sceNetEtherStrton(); int PS4_SYSV_ABI sceNetEventCallbackCreate(); diff --git a/src/emulator.cpp b/src/emulator.cpp index 721151ccc..6649b7bba 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -58,6 +58,7 @@ Emulator::Emulator() { LOG_INFO(Loader, "Branch {}", Common::g_scm_branch); LOG_INFO(Loader, "Description {}", Common::g_scm_desc); + LOG_INFO(Config, "General Logtype: {}", Config::getLogType()); LOG_INFO(Config, "General isNeo: {}", Config::isNeoMode()); LOG_INFO(Config, "GPU isNullGpu: {}", Config::nullGpu()); LOG_INFO(Config, "GPU shouldDumpShaders: {}", Config::dumpShaders()); diff --git a/src/imgui/renderer/imgui_impl_sdl3.cpp b/src/imgui/renderer/imgui_impl_sdl3.cpp index bb194bff7..cecf504a7 100644 --- a/src/imgui/renderer/imgui_impl_sdl3.cpp +++ b/src/imgui/renderer/imgui_impl_sdl3.cpp @@ -581,7 +581,7 @@ static void UpdateMouseData() { // (below) // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries // shouldn't e.g. trigger other operations outside - SDL_CaptureMouse((bd->mouse_buttons_down != 0) ? SDL_TRUE : SDL_FALSE); + SDL_CaptureMouse((bd->mouse_buttons_down != 0) ? true : false); SDL_Window* focused_window = SDL_GetKeyboardFocus(); const bool is_app_focused = (bd->window == focused_window); diff --git a/src/qt_gui/check_update.cpp b/src/qt_gui/check_update.cpp index 023c6e7bb..48adbb88a 100644 --- a/src/qt_gui/check_update.cpp +++ b/src/qt_gui/check_update.cpp @@ -454,6 +454,10 @@ void CheckUpdate::Install() { " sleep 2\n" " extract_file\n" " sleep 2\n" + " if pgrep -f \"Shadps4-qt.AppImage\" > /dev/null; then\n" + " pkill -f \"Shadps4-qt.AppImage\"\n" + " sleep 2\n" + " fi\n" " cp -r \"%2/\"* \"%3/\"\n" " sleep 2\n" " rm \"%3/update.sh\"\n" @@ -525,4 +529,4 @@ void CheckUpdate::Install() { this, tr("Error"), QString(tr("Failed to create the update script file") + ":\n" + scriptFileName)); } -} \ No newline at end of file +} diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index 515804203..bcf5762f2 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -358,8 +358,6 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("dumpShadersCheckBox"); } else if (elementName == "nullGpuCheckBox") { text = tr("nullGpuCheckBox"); - } else if (elementName == "dumpPM4CheckBox") { - text = tr("dumpPM4CheckBox"); } // Debug @@ -376,7 +374,7 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { ui->descriptionText->setText(text.replace("\\n", "\n")); } -bool SettingsDialog::override(QObject* obj, QEvent* event) { +bool SettingsDialog::eventFilter(QObject* obj, QEvent* event) { if (event->type() == QEvent::Enter || event->type() == QEvent::Leave) { if (qobject_cast(obj)) { bool hovered = (event->type() == QEvent::Enter); diff --git a/src/qt_gui/settings_dialog.h b/src/qt_gui/settings_dialog.h index 71307d398..85ae39aaa 100644 --- a/src/qt_gui/settings_dialog.h +++ b/src/qt_gui/settings_dialog.h @@ -21,7 +21,7 @@ public: explicit SettingsDialog(std::span physical_devices, QWidget* parent = nullptr); ~SettingsDialog(); - bool override(QObject* obj, QEvent* event); + bool eventFilter(QObject* obj, QEvent* event) override; void updateNoteTextEdit(const QString& groupName); int exec() override; diff --git a/src/qt_gui/translations/ar.ts b/src/qt_gui/translations/ar.ts index b385b491b..ca23620bb 100644 --- a/src/qt_gui/translations/ar.ts +++ b/src/qt_gui/translations/ar.ts @@ -474,11 +474,6 @@ Enable NULL GPU تمكين وحدة معالجة الرسومات الفارغة - - - Enable PM4 Dumping - PM4 تمكين تفريغ - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox تمكين GPU الافتراضية:\nلأغراض تصحيح الأخطاء التقنية، يقوم بتعطيل عرض اللعبة كما لو لم يكن هناك بطاقة رسومات. - - - dumpPM4CheckBox - تمكين تفريغ PM4:\nلأغراض تصحيح الأخطاء التقنية، يحفظ بيانات تعليمات GPU الأولية في مجلد أثناء معالجتها. - debugDump diff --git a/src/qt_gui/translations/da_DK.ts b/src/qt_gui/translations/da_DK.ts index 73bc37189..0d81e2357 100644 --- a/src/qt_gui/translations/da_DK.ts +++ b/src/qt_gui/translations/da_DK.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktiver virtuel GPU:\nTil teknisk fejlfinding deaktiverer det spilvisning, som om der ikke var et grafikkort. - - - dumpPM4CheckBox - Aktiver dumping af PM4:\nTil teknisk fejlfinding gemmer det rå GPU-kommandoer i en mappe under behandling. - debugDump diff --git a/src/qt_gui/translations/de.ts b/src/qt_gui/translations/de.ts index 771d3bf8e..9e31afd6e 100644 --- a/src/qt_gui/translations/de.ts +++ b/src/qt_gui/translations/de.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU aktivieren - - - Enable PM4 Dumping - PM4-Dumping aktivieren - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Virtuelle GPU aktivieren:\nFür das technische Debugging deaktiviert es die Spielanzeige, als ob keine Grafikkarte vorhanden wäre. - - - dumpPM4CheckBox - PM4-Dumping aktivieren:\nZum technischen Debuggen speichert es rohe GPU-Befehlsdaten in einem Ordner während der Verarbeitung. - debugDump diff --git a/src/qt_gui/translations/el.ts b/src/qt_gui/translations/el.ts index f2265c7d7..de10fc3a8 100644 --- a/src/qt_gui/translations/el.ts +++ b/src/qt_gui/translations/el.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ενεργοποίηση Εικονικής GPU:\nΓια τεχνικό εντοπισμό σφαλμάτων, απενεργοποιεί την εμφάνιση του παιχνιδιού σαν να μην υπάρχει κάρτα γραφικών. - - - dumpPM4CheckBox - Ενεργοποίηση Καταγραφής PM4:\nΓια τεχνικό εντοπισμό σφαλμάτων, αποθηκεύει τις ακατέργαστες εντολές της GPU σε φάκελο κατά την επεξεργασία. - debugDump diff --git a/src/qt_gui/translations/en.ts b/src/qt_gui/translations/en.ts index 59523add9..18c54428f 100644 --- a/src/qt_gui/translations/en.ts +++ b/src/qt_gui/translations/en.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1088,11 +1083,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/es_ES.ts b/src/qt_gui/translations/es_ES.ts index 4242bc91e..86a3e1adc 100644 --- a/src/qt_gui/translations/es_ES.ts +++ b/src/qt_gui/translations/es_ES.ts @@ -474,11 +474,6 @@ Enable NULL GPU Habilitar GPU NULL - - - Enable PM4 Dumping - Habilitar volcado de PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Habilitar GPU Nula:\nPor el bien de la depuración técnica, desactiva el renderizado del juego como si no hubiera tarjeta gráfica. - - - dumpPM4CheckBox - Habilitar la Volcadura de PM4:\nPor el bien de la depuración técnica, guarda los datos de instrucciones crudas de GPU en una carpeta a medida que el emulador los procesa. - debugDump diff --git a/src/qt_gui/translations/fa_IR.ts b/src/qt_gui/translations/fa_IR.ts index 15e07c886..a613af70b 100644 --- a/src/qt_gui/translations/fa_IR.ts +++ b/src/qt_gui/translations/fa_IR.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU فعال کردن - - - Enable PM4 Dumping - PM4 Dumping فعال کردن - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/fi.ts b/src/qt_gui/translations/fi.ts index a2b319280..e4010b872 100644 --- a/src/qt_gui/translations/fi.ts +++ b/src/qt_gui/translations/fi.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ota Null GPU käyttöön:\nTeknistä vianetsintää varten pelin renderöinti estetään niin, että ikään kuin grafiikkakorttia ei olisi. - - - dumpPM4CheckBox - Ota PM4 dumpaus käyttöön:\nTeknistä vianetsintää varten raakoja GPU-ohjeita tallennetaan kansioon emulaattorin käsitellessä sitä. - debugDump diff --git a/src/qt_gui/translations/fr.ts b/src/qt_gui/translations/fr.ts index 05c70f195..b11b585c9 100644 --- a/src/qt_gui/translations/fr.ts +++ b/src/qt_gui/translations/fr.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU - - - Enable PM4 Dumping - Dumper le PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Activer le GPU nul :\nPour le débogage technique, désactive le rendu du jeu comme s'il n'y avait pas de carte graphique. - - - dumpPM4CheckBox - Activer l'exportation PM4 :\nPour le débogage technique, enregistre les données brutes des instructions GPU dans un dossier pendant que l'émulateur les traite. - debugDump diff --git a/src/qt_gui/translations/hu_HU.ts b/src/qt_gui/translations/hu_HU.ts index fb348ee29..5986193c4 100644 --- a/src/qt_gui/translations/hu_HU.ts +++ b/src/qt_gui/translations/hu_HU.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU Engedélyezése - - - Enable PM4 Dumping - PM4 Dumpolás Engedélyezése - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU engedélyezése:\nMűszaki hibaelhárítás céljából letiltja a játék renderelését, mintha nem lenne grafikus kártya. - - - dumpPM4CheckBox - PM4 dumpolás engedélyezése:\nMűszaki hibaelhárítás céljából a nyers GPU utasítási adatokat elmenti egy mappába, ahogy az emulátor feldolgozza őket. - debugDump diff --git a/src/qt_gui/translations/id.ts b/src/qt_gui/translations/id.ts index 86c58c6ce..274029bd0 100644 --- a/src/qt_gui/translations/id.ts +++ b/src/qt_gui/translations/id.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktifkan GPU Null:\nUntuk tujuan debugging teknis, menonaktifkan rendering permainan seolah-olah tidak ada kartu grafis. - - - dumpPM4CheckBox - Aktifkan Pembuangan PM4:\nUntuk tujuan debugging teknis, menyimpan data instruksi GPU mentah ke folder saat emulator memprosesnya. - debugDump diff --git a/src/qt_gui/translations/it.ts b/src/qt_gui/translations/it.ts index f5ea9a65c..07976865c 100644 --- a/src/qt_gui/translations/it.ts +++ b/src/qt_gui/translations/it.ts @@ -474,11 +474,6 @@ Enable NULL GPU Abilita NULL GPU - - - Enable PM4 Dumping - Abilita Dump PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Abilita GPU Null:\nPer scopi di debug tecnico, disabilita il rendering del gioco come se non ci fosse alcuna scheda grafica. - - - dumpPM4CheckBox - Abilita Pompaggio PM4:\nPer scopi di debug tecnico, salva i dati delle istruzioni GPU grezze in una cartella mentre l'emulatore li elabora. - debugDump diff --git a/src/qt_gui/translations/ja_JP.ts b/src/qt_gui/translations/ja_JP.ts index 166100db6..c3444906b 100644 --- a/src/qt_gui/translations/ja_JP.ts +++ b/src/qt_gui/translations/ja_JP.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPUを有効にする - - - Enable PM4 Dumping - PM4ダンプを有効にする - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPUを有効にする:\n技術的なデバッグの目的で、グラフィックスカードがないかのようにゲームのレンダリングを無効にします。 - - - dumpPM4CheckBox - PM4ダンプを有効にする:\n技術的なデバッグの目的で、エミュレーターが処理している間に生のGPU命令データをフォルダーに保存します。 - debugDump diff --git a/src/qt_gui/translations/ko_KR.ts b/src/qt_gui/translations/ko_KR.ts index 93ceb9e35..e816e2f4b 100644 --- a/src/qt_gui/translations/ko_KR.ts +++ b/src/qt_gui/translations/ko_KR.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Enable Null GPU:\nFor the sake of technical debugging, disables game rendering as if there were no graphics card. - - - dumpPM4CheckBox - Enable PM4 Dumping:\nFor the sake of technical debugging, saves raw GPU instruction data to a folder as the emulator processes it. - debugDump diff --git a/src/qt_gui/translations/lt_LT.ts b/src/qt_gui/translations/lt_LT.ts index cac8ebbfc..d5b4ff3ad 100644 --- a/src/qt_gui/translations/lt_LT.ts +++ b/src/qt_gui/translations/lt_LT.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Įjungti tuščią GPU:\nTechninio derinimo tikslais išjungia žaidimo renderiavimą, tarsi nebūtų grafikos plokštės. - - - dumpPM4CheckBox - Įjungti PM4 išmetimą:\nTechninio derinimo tikslais saugo žalius GPU nurodymų duomenis į aplanką, kai emuliatorius juos apdoroja. - debugDump diff --git a/src/qt_gui/translations/nb.ts b/src/qt_gui/translations/nb.ts index e0bc1a550..334600950 100644 --- a/src/qt_gui/translations/nb.ts +++ b/src/qt_gui/translations/nb.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktiver Null GPU:\nFor teknisk feilsøking deaktiverer spillrendering som om det ikke var noe grafikkort. - - - dumpPM4CheckBox - Aktiver PM4 dumping:\nFor teknisk feilsøking lagrer rå GPU-instruksjonsdata i en mappe mens emulatoren behandler dem. - debugDump diff --git a/src/qt_gui/translations/nl.ts b/src/qt_gui/translations/nl.ts index 29a60ecc8..6e49d4640 100644 --- a/src/qt_gui/translations/nl.ts +++ b/src/qt_gui/translations/nl.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU inschakelen:\nVoor technische foutopsporing schakelt de game-rendering uit alsof er geen grafische kaart is. - - - dumpPM4CheckBox - PM4 dumpen inschakelen:\nVoor technische foutopsporing slaat het ruwe GPU-instructiegegevens op in een map terwijl de emulator ze verwerkt. - debugDump diff --git a/src/qt_gui/translations/pl_PL.ts b/src/qt_gui/translations/pl_PL.ts index bd772b0fe..e95b8ba0c 100644 --- a/src/qt_gui/translations/pl_PL.ts +++ b/src/qt_gui/translations/pl_PL.ts @@ -474,11 +474,6 @@ Enable NULL GPU Wyłącz kartę graficzną - - - Enable PM4 Dumping - Włącz zgrywanie PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Włącz Null GPU:\nDla technicznego debugowania dezaktywuje renderowanie gry tak, jakby nie było karty graficznej. - - - dumpPM4CheckBox - Włącz zrzucanie PM4:\nDla technicznego debugowania zapisuje surowe dane instrukcji GPU w folderze, gdy emulator je przetwarza. - debugDump diff --git a/src/qt_gui/translations/pt_BR.ts b/src/qt_gui/translations/pt_BR.ts index 38836b1d0..e1570b2cd 100644 --- a/src/qt_gui/translations/pt_BR.ts +++ b/src/qt_gui/translations/pt_BR.ts @@ -474,11 +474,6 @@ Enable NULL GPU Ativar GPU NULA - - - Enable PM4 Dumping - Ativar Dumping de PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Ativar GPU NULA:\nDesativa a renderização do jogo para fins de depuração técnica, como se não houvesse nenhuma placa gráfica. - - - dumpPM4CheckBox - Ativar Dumping de PM4:\nArmazena os dados de instrução bruta da GPU em uma pasta enquanto o emulador os processa, para fins de depuração técnica. Recomendado deixar desativado. - debugDump diff --git a/src/qt_gui/translations/ro_RO.ts b/src/qt_gui/translations/ro_RO.ts index a5c3783bb..e98b7e5c9 100644 --- a/src/qt_gui/translations/ro_RO.ts +++ b/src/qt_gui/translations/ro_RO.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Activează GPU Null:\nÎn scopuri de depanare tehnică, dezactivează redarea jocului ca și cum nu ar exista o placă grafică. - - - dumpPM4CheckBox - Activează salvarea PM4:\nÎn scopuri de depanare tehnică, salvează datele brute ale instrucțiunilor GPU într-un folder pe măsură ce emulatorul le procesează. - debugDump diff --git a/src/qt_gui/translations/ru_RU.ts b/src/qt_gui/translations/ru_RU.ts index 13cc49f20..aaff66ef9 100644 --- a/src/qt_gui/translations/ru_RU.ts +++ b/src/qt_gui/translations/ru_RU.ts @@ -474,11 +474,6 @@ Enable NULL GPU Включить NULL GPU - - - Enable PM4 Dumping - Включить дамп PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Включить NULL GPU:\nДля технической отладки отключает рендеринг игры так, как будто графической карты нет. - - - dumpPM4CheckBox - Включить дамп PM4:\nДля технической отладки сохраняет необработанные данные инструкций GPU в папку, пока эмулятор их обрабатывает. - debugDump diff --git a/src/qt_gui/translations/sq.ts b/src/qt_gui/translations/sq.ts index d9f1d3859..c6e4c018d 100644 --- a/src/qt_gui/translations/sq.ts +++ b/src/qt_gui/translations/sq.ts @@ -474,11 +474,6 @@ Enable NULL GPU Aktivizo GPU-në NULL - - - Enable PM4 Dumping - Aktivizo Zbrazjen PM4 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Aktivizo GPU Null:\nPër qëllime të debugimit teknik, deaktivizon renditjen e lojës sikur nuk do të kishte një kartë grafike. - - - dumpPM4CheckBox - Aktivizo dump-in e PM4:\nPër qëllime të debugimit teknik, ruan të dhënat e instruksioneve të GPU-së në një folder ndërsa emulatori i përpunon ato. - debugDump diff --git a/src/qt_gui/translations/tr_TR.ts b/src/qt_gui/translations/tr_TR.ts index 32e5c4bd6..5cd71af34 100644 --- a/src/qt_gui/translations/tr_TR.ts +++ b/src/qt_gui/translations/tr_TR.ts @@ -474,11 +474,6 @@ Enable NULL GPU NULL GPU'yu Etkinleştir - - - Enable PM4 Dumping - PM4 Kaydını Etkinleştir - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Null GPU'yu Etkinleştir:\nTeknik hata ayıklama amacıyla, oyunun render edilmesini grafik kartı yokmuş gibi devre dışı bırakır. - - - dumpPM4CheckBox - PM4 Dışa Aktarmayı Etkinleştir:\nTeknik hata ayıklama amacıyla, emülatör bunları işlerken GPU komut verilerini bir klasöre kaydeder. - debugDump diff --git a/src/qt_gui/translations/vi_VN.ts b/src/qt_gui/translations/vi_VN.ts index 8f377f2a7..523683621 100644 --- a/src/qt_gui/translations/vi_VN.ts +++ b/src/qt_gui/translations/vi_VN.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox Bật GPU Null:\nĐể mục đích gỡ lỗi kỹ thuật, vô hiệu hóa việc kết xuất trò chơi như thể không có card đồ họa. - - - dumpPM4CheckBox - Bật xuất PM4:\nĐể mục đích gỡ lỗi kỹ thuật, lưu dữ liệu lệnh GPU vào một thư mục khi trình giả lập xử lý chúng. - debugDump diff --git a/src/qt_gui/translations/zh_CN.ts b/src/qt_gui/translations/zh_CN.ts index 0eae5a5bd..f2abc4f4b 100644 --- a/src/qt_gui/translations/zh_CN.ts +++ b/src/qt_gui/translations/zh_CN.ts @@ -474,11 +474,6 @@ Enable NULL GPU 启用 NULL GPU - - - Enable PM4 Dumping - 启用 PM4 转储 - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox 启用空 GPU:\n为了技术调试,将游戏渲染禁用,仿佛没有图形卡。 - - - dumpPM4CheckBox - 启用 PM4 转储:\n为了技术调试,在模拟器处理时将原始 GPU 指令数据保存到文件夹中。 - debugDump diff --git a/src/qt_gui/translations/zh_TW.ts b/src/qt_gui/translations/zh_TW.ts index cead22ecf..2d34f8d12 100644 --- a/src/qt_gui/translations/zh_TW.ts +++ b/src/qt_gui/translations/zh_TW.ts @@ -474,11 +474,6 @@ Enable NULL GPU Enable NULL GPU - - - Enable PM4 Dumping - Enable PM4 Dumping - Debug @@ -1053,11 +1048,6 @@ nullGpuCheckBox 啟用空GPU:\n為了技術調試,禁用遊戲渲染,彷彿沒有顯示卡。 - - - dumpPM4CheckBox - 啟用PM4轉儲:\n為了技術調試,將原始GPU指令數據在模擬器處理時保存到文件夾中。 - debugDump diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index a585f3283..f90e9db77 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -27,8 +27,10 @@ static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType case AmdGpu::PrimitiveType::TriangleList: case AmdGpu::PrimitiveType::TriangleStrip: return spv::ExecutionMode::Triangles; + case AmdGpu::PrimitiveType::AdjTriangleList: + return spv::ExecutionMode::InputTrianglesAdjacency; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown input primitive type {}", u32(type)); } } @@ -41,7 +43,7 @@ static constexpr spv::ExecutionMode GetOutputPrimitiveType(AmdGpu::GsOutputPrimi case AmdGpu::GsOutputPrimitiveType::TriangleStrip: return spv::ExecutionMode::OutputTriangleStrip; default: - UNREACHABLE(); + UNREACHABLE_MSG("Unknown output primitive type {}", u32(type)); } } @@ -68,6 +70,8 @@ ArgType Arg(EmitContext& ctx, const IR::Value& arg) { return arg.ScalarReg(); } else if constexpr (std::is_same_v) { return arg.VectorReg(); + } else if constexpr (std::is_same_v) { + return arg.StringLiteral(); } } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index ec86e5cc9..6ae1ef24a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -48,6 +48,7 @@ void EmitPrologue(EmitContext& ctx); void EmitEpilogue(EmitContext& ctx); void EmitDiscard(EmitContext& ctx); void EmitDiscardCond(EmitContext& ctx, Id condition); +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id arg0, Id arg1, Id arg2, Id arg3, Id arg4); void EmitBarrier(EmitContext& ctx); void EmitWorkgroupMemoryBarrier(EmitContext& ctx); void EmitDeviceMemoryBarrier(EmitContext& ctx); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index c12e4997f..e9ffdcce8 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp @@ -3,6 +3,7 @@ #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h" #include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/ir/debug_print.h" namespace Shader::Backend::SPIRV { @@ -57,4 +58,11 @@ void EmitEndPrimitive(EmitContext& ctx, const IR::Value& stream) { throw NotImplementedException("Geometry streams"); } +void EmitDebugPrint(EmitContext& ctx, IR::Inst* inst, Id fmt, Id arg0, Id arg1, Id arg2, Id arg3) { + IR::DebugPrintFlags flags = inst->Flags(); + std::array fmt_args = {arg0, arg1, arg2, arg3}; + auto fmt_args_span = std::span(fmt_args.begin(), fmt_args.begin() + flags.num_args); + ctx.OpDebugPrintf(fmt, fmt_args_span); +} + } // namespace Shader::Backend::SPIRV diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index f5b60d51d..5eee656dd 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -34,14 +34,17 @@ std::string_view StageName(Stage stage) { throw InvalidArgument("Invalid stage {}", u32(stage)); } -static constexpr u32 NumVertices(AmdGpu::GsOutputPrimitiveType type) { +static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) { switch (type) { - case AmdGpu::GsOutputPrimitiveType::PointList: + case AmdGpu::PrimitiveType::PointList: return 1u; - case AmdGpu::GsOutputPrimitiveType::LineStrip: + case AmdGpu::PrimitiveType::LineList: return 2u; - case AmdGpu::GsOutputPrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::TriangleList: + case AmdGpu::PrimitiveType::TriangleStrip: return 3u; + case AmdGpu::PrimitiveType::AdjTriangleList: + return 6u; default: UNREACHABLE(); } @@ -88,6 +91,8 @@ Id EmitContext::Def(const IR::Value& value) { return ConstF32(value.F32()); case IR::Type::F64: return Constant(F64[1], value.F64()); + case IR::Type::StringLiteral: + return String(value.StringLiteral()); default: throw NotImplementedException("Immediate type {}", value.Type()); } @@ -321,16 +326,15 @@ void EmitContext::DefineInputs() { MemberDecorate(gl_per_vertex, 2, spv::Decoration::BuiltIn, static_cast(spv::BuiltIn::ClipDistance)); Decorate(gl_per_vertex, spv::Decoration::Block); - const auto vertices_in = - TypeArray(gl_per_vertex, ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0]))); + const auto num_verts_in = NumVertices(runtime_info.gs_info.in_primitive); + const auto vertices_in = TypeArray(gl_per_vertex, ConstU32(num_verts_in)); gl_in = Name(DefineVar(vertices_in, spv::StorageClass::Input), "gl_in"); interfaces.push_back(gl_in); const auto num_params = runtime_info.gs_info.in_vertex_data_size / 4 - 1u; for (int param_id = 0; param_id < num_params; ++param_id) { const IR::Attribute param{IR::Attribute::Param0 + param_id}; - const Id type{ - TypeArray(F32[4], ConstU32(NumVertices(runtime_info.gs_info.out_primitive[0])))}; + const Id type{TypeArray(F32[4], ConstU32(num_verts_in))}; const Id id{DefineInput(type, param_id)}; Name(id, fmt::format("in_attr{}", param_id)); input_params[param_id] = {id, input_f32, F32[1], 4}; diff --git a/src/shader_recompiler/frontend/copy_shader.cpp b/src/shader_recompiler/frontend/copy_shader.cpp index a194aec95..363c1c821 100644 --- a/src/shader_recompiler/frontend/copy_shader.cpp +++ b/src/shader_recompiler/frontend/copy_shader.cpp @@ -15,18 +15,18 @@ CopyShaderData ParseCopyShader(const std::span& code) { ASSERT_MSG(code[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm"); std::array offsets{}; - std::fill(offsets.begin(), offsets.end(), -1); + offsets.fill(-1); + + std::array sources{}; + sources.fill(-1); CopyShaderData data{}; - Gcn::OperandField sgpr{}; auto last_attr{IR::Attribute::Position0}; - s32 soffset{0}; while (!code_slice.atEnd()) { auto inst = decoder.decodeInstruction(code_slice); switch (inst.opcode) { case Gcn::Opcode::S_MOVK_I32: { - sgpr = inst.dst[0].field; - soffset = inst.control.sopk.simm; + sources[inst.dst[0].code] = inst.control.sopk.simm; break; } case Gcn::Opcode::EXP: { @@ -46,8 +46,9 @@ CopyShaderData ParseCopyShader(const std::span& code) { case Gcn::Opcode::BUFFER_LOAD_DWORD: { offsets[inst.src[1].code] = inst.control.mubuf.offset; if (inst.src[3].field != Gcn::OperandField::ConstZero) { - ASSERT(inst.src[3].field == sgpr); - offsets[inst.src[1].code] += soffset; + const u32 index = inst.src[3].code; + ASSERT(sources[index] != -1); + offsets[inst.src[1].code] += sources[index]; } break; } @@ -59,6 +60,7 @@ CopyShaderData ParseCopyShader(const std::span& code) { if (last_attr != IR::Attribute::Position0) { data.num_attrs = static_cast(last_attr) - static_cast(IR::Attribute::Param0) + 1; } + return data; } diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 7fc7be753..78a6805fd 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include #include "common/assert.h" diff --git a/src/shader_recompiler/ir/debug_print.h b/src/shader_recompiler/ir/debug_print.h new file mode 100644 index 000000000..1ab1575de --- /dev/null +++ b/src/shader_recompiler/ir/debug_print.h @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/bit_field.h" +#include "shader_recompiler/ir/opcodes.h" +#include "src/common/types.h" + +#pragma once + +namespace Shader::IR { + +constexpr size_t DEBUGPRINT_NUM_FORMAT_ARGS = NumArgsOf(IR::Opcode::DebugPrint) - 1; + +union DebugPrintFlags { + u32 raw; + // For now, only flag is the number of variadic format args actually used + // So bitfield not really needed + BitField<0, 32, u32> num_args; +}; + +} // namespace Shader::IR \ No newline at end of file diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 01336c567..4f5eb5c33 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1,10 +1,15 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include +#include +#include "common/assert.h" #include "shader_recompiler/exception.h" +#include "shader_recompiler/ir/debug_print.h" #include "shader_recompiler/ir/ir_emitter.h" +#include "shader_recompiler/ir/opcodes.h" #include "shader_recompiler/ir/value.h" namespace Shader::IR { @@ -1553,6 +1558,38 @@ void IREmitter::ImageWrite(const Value& handle, const Value& coords, const Value Inst(Opcode::ImageWrite, Flags{info}, handle, coords, color); } +// Debug print maps to SPIRV's NonSemantic DebugPrintf instruction +// Renderdoc will hook in its own implementation of the SPIRV instruction +// Renderdoc accepts format specifiers, e.g. %u, listed here: +// https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/docs/debug_printf.md +// +// fmt must be a string literal (pointer is shallow copied into a Value) +// Example usage: +// ir.DebugPrint("invocation xyz: (%u, %u, %u)", +// {ir.GetVectorReg(IR::VectorReg::V0), +// ir.GetVectorReg(IR::VectorReg::V1), +// ir.GetVectorReg(IR::VectorReg::V2)}); +void IREmitter::DebugPrint(const char* fmt, boost::container::small_vector format_args) { + std::array args; + + ASSERT_MSG(format_args.size() < DEBUGPRINT_NUM_FORMAT_ARGS, + "DebugPrint only supports up to {} format args", DEBUGPRINT_NUM_FORMAT_ARGS); + + for (int i = 0; i < format_args.size(); i++) { + args[i] = format_args[i]; + } + + for (int i = format_args.size(); i < DEBUGPRINT_NUM_FORMAT_ARGS; i++) { + args[i] = Inst(Opcode::Void); + } + + IR::Value fmt_val{fmt}; + + DebugPrintFlags flags; + flags.num_args.Assign(format_args.size()); + Inst(Opcode::DebugPrint, Flags{flags}, fmt_val, args[0], args[1], args[2], args[3]); +} + void IREmitter::EmitVertex() { Inst(Opcode::EmitVertex); } diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 8657c430b..2ebac037e 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -6,6 +6,7 @@ #include #include +#include "shader_recompiler/info.h" #include "shader_recompiler/ir/attribute.h" #include "shader_recompiler/ir/basic_block.h" #include "shader_recompiler/ir/condition.h" @@ -43,6 +44,7 @@ public: void Epilogue(); void Discard(); void Discard(const U1& cond); + void DebugPrint(const char* fmt, boost::container::small_vector args); void Barrier(); void WorkgroupMemoryBarrier(); diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index 8d606a6cc..f0b4882b3 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -89,6 +89,7 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::ImageAtomicOr32: case Opcode::ImageAtomicXor32: case Opcode::ImageAtomicExchange32: + case Opcode::DebugPrint: case Opcode::EmitVertex: case Opcode::EmitPrimitive: return true; diff --git a/src/shader_recompiler/ir/opcodes.h b/src/shader_recompiler/ir/opcodes.h index 06f1a6117..2cea70090 100644 --- a/src/shader_recompiler/ir/opcodes.h +++ b/src/shader_recompiler/ir/opcodes.h @@ -51,6 +51,7 @@ constexpr Type F32x4{Type::F32x4}; constexpr Type F64x2{Type::F64x2}; constexpr Type F64x3{Type::F64x3}; constexpr Type F64x4{Type::F64x4}; +constexpr Type StringLiteral{Type::StringLiteral}; constexpr OpcodeMeta META_TABLE[]{ #define OPCODE(name_token, type_token, ...) \ @@ -81,7 +82,7 @@ constexpr u8 NUM_ARGS[]{ } /// Get the number of arguments an opcode accepts -[[nodiscard]] inline size_t NumArgsOf(Opcode op) noexcept { +[[nodiscard]] constexpr inline size_t NumArgsOf(Opcode op) noexcept { return static_cast(Detail::NUM_ARGS[static_cast(op)]); } diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index c69dc90a5..41e94ab13 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -14,6 +14,7 @@ OPCODE(Prologue, Void, OPCODE(Epilogue, Void, ) OPCODE(Discard, Void, ) OPCODE(DiscardCond, Void, U1, ) +OPCODE(DebugPrint, Void, StringLiteral, Opaque, Opaque, Opaque, Opaque, ) // Constant memory operations OPCODE(ReadConst, U32, U32x2, U32, ) diff --git a/src/shader_recompiler/ir/type.cpp b/src/shader_recompiler/ir/type.cpp index 9d303b4db..08157f108 100644 --- a/src/shader_recompiler/ir/type.cpp +++ b/src/shader_recompiler/ir/type.cpp @@ -9,10 +9,9 @@ namespace Shader::IR { std::string NameOf(Type type) { static constexpr std::array names{ - "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", - "U64", "F16", "F32", "F64", "U32x2", "U32x3", "U32x4", "F16x2", "F16x3", - "F16x4", "F32x2", "F32x3", "F32x4", "F64x2", "F64x3", "F64x4", - }; + "Opaque", "Label", "Reg", "Pred", "Attribute", "U1", "U8", "U16", "U32", + "U64", "F16", "F32", "F64", "U32x2", "U32x3", "U32x4", "F16x2", "F16x3", + "F16x4", "F32x2", "F32x3", "F32x4", "F64x2", "F64x3", "F64x4", "StringLiteral"}; const size_t bits{static_cast(type)}; if (bits == 0) { return "Void"; diff --git a/src/shader_recompiler/ir/type.h b/src/shader_recompiler/ir/type.h index d7f47e1de..ec855a77e 100644 --- a/src/shader_recompiler/ir/type.h +++ b/src/shader_recompiler/ir/type.h @@ -36,6 +36,7 @@ enum class Type { F64x2 = 1 << 22, F64x3 = 1 << 23, F64x4 = 1 << 24, + StringLiteral = 1 << 25, }; DECLARE_ENUM_FLAG_OPERATORS(Type) diff --git a/src/shader_recompiler/ir/value.cpp b/src/shader_recompiler/ir/value.cpp index 86e5dd141..cf7a70f76 100644 --- a/src/shader_recompiler/ir/value.cpp +++ b/src/shader_recompiler/ir/value.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include "shader_recompiler/ir/value.h" namespace Shader::IR { @@ -27,6 +28,8 @@ Value::Value(u64 value) noexcept : type{Type::U64}, imm_u64{value} {} Value::Value(f64 value) noexcept : type{Type::F64}, imm_f64{value} {} +Value::Value(const char* value) noexcept : type{Type::StringLiteral}, string_literal{value} {} + IR::Type Value::Type() const noexcept { if (IsPhi()) { // The type of a phi node is stored in its flags @@ -69,6 +72,8 @@ bool Value::operator==(const Value& other) const { case Type::U64: case Type::F64: return imm_u64 == other.imm_u64; + case Type::StringLiteral: + return std::string_view(string_literal) == other.string_literal; case Type::U32x2: case Type::U32x3: case Type::U32x4: diff --git a/src/shader_recompiler/ir/value.h b/src/shader_recompiler/ir/value.h index db939eaa5..060b9d2bb 100644 --- a/src/shader_recompiler/ir/value.h +++ b/src/shader_recompiler/ir/value.h @@ -39,6 +39,7 @@ public: explicit Value(f32 value) noexcept; explicit Value(u64 value) noexcept; explicit Value(f64 value) noexcept; + explicit Value(const char* value) noexcept; [[nodiscard]] bool IsIdentity() const noexcept; [[nodiscard]] bool IsPhi() const noexcept; @@ -60,6 +61,7 @@ public: [[nodiscard]] f32 F32() const; [[nodiscard]] u64 U64() const; [[nodiscard]] f64 F64() const; + [[nodiscard]] const char* StringLiteral() const; [[nodiscard]] bool operator==(const Value& other) const; [[nodiscard]] bool operator!=(const Value& other) const; @@ -78,6 +80,7 @@ private: f32 imm_f32; u64 imm_u64; f64 imm_f64; + const char* string_literal; }; }; static_assert(static_cast(IR::Type::Void) == 0, "memset relies on IR::Type being zero"); @@ -348,6 +351,14 @@ inline f64 Value::F64() const { return imm_f64; } +inline const char* Value::StringLiteral() const { + if (IsIdentity()) { + return inst->Arg(0).StringLiteral(); + } + DEBUG_ASSERT(type == Type::StringLiteral); + return string_literal; +} + [[nodiscard]] inline bool IsPhi(const Inst& inst) { return inst.GetOpcode() == Opcode::Phi; }