Compare commits

...

16 Commits

Author SHA1 Message Date
lightningterror
bd9dcbe441 GS/D3D: Default to DX12 on older GCN amd cards. 2026-01-06 20:09:04 +01:00
PCSX2 Bot
2a1f29c641 [ci skip] Qt: Update Base Translation. 2026-01-06 20:08:18 +01:00
TheLastRar
38883e8df4 GS/DX12: Use cmdlist parameter for read depth transitions 2026-01-06 20:08:02 +01:00
PCSX2 Bot
f971040912 [ci skip] PAD: Update to latest controller database. 2026-01-06 20:07:43 +01:00
Jordan
9aac7e8426 [ci skip] GameDB: CMR 2005 Fixes (#13782)
hotpatch!!!
2026-01-05 17:44:44 -05:00
Ty Lamontagne
96284205a1 [ci skip] Release 2.6 2026-01-04 14:20:16 -05:00
RedPanda4552
4a1d9d31d0 Achievements: Store token to separate ini 2026-01-04 13:56:14 -05:00
Ty
12d6087f2a Translations: Syncing Crowdin translations 2026-01-04 13:55:43 -05:00
Ty
251962c415 Qt: Don't show the dev name if it equals the displayname 2026-01-04 13:49:18 -05:00
Ty
1bdd7d2352 FSUI: Don't show the name if it equals the displayname when listing 2026-01-04 13:49:18 -05:00
SternXD
7b98259ea1 FullscreenUI: Update auto mapping to include device names with display names 2026-01-03 23:59:57 -05:00
Ty
ee8166d1fe Debugger: Check PC instead of cycles when stopping for a breakpoint 2026-01-03 10:14:21 -05:00
TheLastRar
43e073a18d GS/DX12: Fix validation errors when depth testing and sampling 2026-01-01 01:20:13 +01:00
JordanTheToaster
bc41666d53 GameDB: Various fixes 2026-01-01 01:09:27 +01:00
PCSX2 Bot
5b85d6a758 [ci skip] PAD: Update to latest controller database. 2025-12-29 17:04:38 +01:00
TheLastRar
1fdc000815 GS/DX12: Don't move to next command list until after wait 2025-12-29 17:04:28 +01:00
59 changed files with 202587 additions and 152865 deletions

View File

@@ -4,6 +4,17 @@ on:
schedule:
- cron: "0 0 * * *" # Every day at 12am UTC.
workflow_dispatch: # As well as manually.
inputs:
stableBuild:
description: 'Build stable version'
required: false
type: boolean
default: false
publish:
description: 'Publish to Flathub'
required: false
type: boolean
default: true
jobs:
@@ -52,8 +63,8 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: true
publish: ${{ inputs.publish || true }}
fetchTags: true
stableBuild: false
stableBuild: ${{ inputs.stableBuild || false }}
secrets: inherit

View File

@@ -12,7 +12,7 @@ on:
- master
workflow_dispatch:
inputs:
is_prelease:
is_prerelease:
description: 'Should be a pre-release?'
required: true
default: 'true'
@@ -73,7 +73,7 @@ jobs:
with:
body_path: ./release-notes.md
draft: true
prerelease: ${{ github.event_name != 'workflow_dispatch' || inputs.is_prelease == 'true' }}
prerelease: ${{ github.event_name != 'workflow_dispatch' || inputs.is_prerelease == 'true' }}
tag_name: ${{ steps.tag_version.outputs.new_tag }}
- name: Create a GitHub Release (Push)
@@ -100,7 +100,7 @@ jobs:
cmakeflags: ""
buildAppImage: true
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
secrets: inherit
build_linux_flatpak:
@@ -114,9 +114,9 @@ jobs:
artifactPrefixName: "PCSX2-linux-Qt-x64-flatpak"
compiler: clang
cmakeflags: ""
publish: false
publish: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }} # prerelease builds are published by the cron job
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ inputs.is_prerelease == 'false' }}
secrets: inherit
# Windows
@@ -133,7 +133,7 @@ jobs:
buildSystem: cmake
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
secrets: inherit
# MacOS
@@ -147,7 +147,7 @@ jobs:
jobName: "MacOS Build"
artifactPrefixName: "PCSX2-macos-Qt"
fetchTags: true
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prelease == 'false' }}
stableBuild: ${{ github.event_name == 'workflow_dispatch' && inputs.is_prerelease == 'false' }}
sign_and_notarize: true
secrets: inherit

View File

@@ -17830,6 +17830,8 @@ SLES-51393:
SLES-51397:
name: "IndyCar Series"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 5 # Aligns post-processing and fixes depth line.
SLES-51398:
name: "World Championship Snooker 2003"
region: "PAL-E"
@@ -19953,6 +19955,8 @@ SLES-52298:
name: "IndyCar Series 2005"
region: "PAL-M5"
compat: 5
gsHWFixes:
halfPixelOffset: 5 # Aligns post-processing and fixes depth line.
SLES-52308:
name: "Karaoke Stage"
region: "PAL-M5"
@@ -20123,6 +20127,9 @@ SLES-52378:
name: "Euro Rally Champion"
region: "PAL-M5"
compat: 5
gsHWFixes:
halfPixelOffset: 5 # Aligns post-processing and fixes depth line.
textureInsideRT: 1 # Fixes broken fog rendering.
SLES-52379:
name: "Shrek 2"
region: "PAL-E"
@@ -20887,10 +20894,8 @@ SLES-52636:
gameFixes:
- FullVU0SyncHack # Fixes in-game timer.
gsHWFixes:
recommendedBlendingLevel: 3 # Fixes missing lighting and car reflections.
halfPixelOffset: 1 # Fixes 4 split lines in stage intros.
autoFlush: 1 # Fixes incorrect colors.
alignSprite: 1 # Fixes vertical lines such as in FMVs.
minimumBlendingLevel: 3 # Fixes missing lighting and car reflections.
halfPixelOffset: 4 # Fixes lines in game and FMVs.
SLES-52637:
name: "TOCA Race Driver 2"
region: "PAL-M5"
@@ -25057,6 +25062,8 @@ SLES-53957:
SLES-53958:
name: "Noble Racing"
region: "PAL-E"
gsHWFixes:
halfPixelOffset: 5 # Aligns post-processing and fixes depth line.
SLES-53959:
name: "Pac-Man World 3"
region: "PAL-M5"
@@ -66984,6 +66991,8 @@ SLUS-20641:
name: "IndyCar Series"
region: "NTSC-U"
compat: 5
gsHWFixes:
halfPixelOffset: 5 # Aligns post-processing and fixes depth line.
SLUS-20642:
name: "Auto Modellista"
region: "NTSC-U"

View File

@@ -245,7 +245,8 @@
03000000b62500000100000000000000,Gametel GT004 01,a:b3,b:b0,dpdown:b10,dpleft:b9,dpright:b8,dpup:b11,leftshoulder:b4,rightshoulder:b5,start:b7,x:b1,y:b2,platform:Windows,
030000008f0e00001411000000000000,Gamo2 Divaller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
03000000120c0000a857000000000000,Gator Claw,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
03000000c9110000f055000000000000,GC100XF,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000c21100000791000000000000,Be1 GC101 Controller 1.03,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
03000000c9110000f055000000000000,Be1 GC100XF Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000008305000009a0000000000000,Genius,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
@@ -850,6 +851,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
# Mac OS X
030000008f0e00000300000009010000,2 In 1 Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Mac OS X,
03000000c82d00001930000000000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
03000000c82d00001930000000020000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
03000000c82d00001930000001000000,8BitDo 64,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,platform:Mac OS X,
03000000c82d00000031000001000000,8BitDo Adapter,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
@@ -895,7 +897,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c82d00001290000001000000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00004028000000010000,8BitDo SN30,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a5,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000161000000010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000260000001000000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00000261000000010000,8BitDo SN30 Pro Plus,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Mac OS X,
03000000c82d00001230000000010000,8BitDo Ultimate,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,

View File

@@ -86,6 +86,7 @@ namespace QtHost
//////////////////////////////////////////////////////////////////////////
static QTimer* s_settings_save_timer = nullptr;
static std::unique_ptr<INISettingsInterface> s_base_settings_interface;
static std::unique_ptr<INISettingsInterface> s_secrets_settings_interface;
static bool s_batch_mode = false;
static bool s_nogui_mode = false;
static bool s_start_big_picture_mode = false;
@@ -1307,6 +1308,7 @@ bool QtHost::InitializeConfig()
// Write crash dumps to the data directory, since that'll be accessible for certain.
CrashHandler::SetWriteDirectory(EmuFolders::DataRoot);
// Load main settings ini
const std::string path = Path::Combine(EmuFolders::Settings, "PCSX2.ini");
const bool settings_exists = FileSystem::FileExists(path.c_str());
Console.WriteLnFmt("Loading config from {}.", path);
@@ -1347,6 +1349,29 @@ bool QtHost::InitializeConfig()
SaveSettings();
}
// Layer secrets ini on top
const std::string secrets_path = Path::Combine(EmuFolders::Settings, "secrets.ini");
const bool secrets_settings_exists = FileSystem::FileExists(secrets_path.c_str());
Console.WriteLnFmt("Loading secrets from {}.", secrets_path);
s_secrets_settings_interface = std::make_unique<INISettingsInterface>(std::move(secrets_path));
Host::Internal::SetSecretsSettingsLayer(s_secrets_settings_interface.get());
if (!secrets_settings_exists || !s_secrets_settings_interface->Load())
{
if (!s_base_settings_interface->Save(&error))
{
QMessageBox::critical(
nullptr, QStringLiteral("PCSX2"),
QStringLiteral(
"Failed to save secrets to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You "
"can also try portable mode by creating portable.txt in the same directory you installed PCSX2 into.")
.arg(QString::fromStdString(s_secrets_settings_interface->GetFileName()))
.arg(QString::fromStdString(error.GetDescription())));
return false;
}
}
// Setup wizard was incomplete last time?
s_run_setup_wizard =
s_run_setup_wizard || s_base_settings_interface->GetBoolValue("UI", "SetupWizardIncomplete", false);

View File

@@ -202,7 +202,11 @@ void ControllerBindingWidget::onAutomaticBindingClicked()
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
QAction* action;
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
action = menu.addAction(dev.first);
else
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;
@@ -1152,7 +1156,11 @@ void USBDeviceWidget::onAutomaticBindingClicked()
for (const QPair<QString, QString>& dev : m_dialog->getDeviceList())
{
// we set it as data, because the device list could get invalidated while the menu is up
QAction* action = menu.addAction(QStringLiteral("%1 (%2)").arg(dev.first).arg(dev.second));
QAction* action;
if(dev.first.compare(dev.second, Qt::CaseInsensitive) == 0)
action = menu.addAction(dev.first);
else
action = menu.addAction(QStringLiteral("%1: %2").arg(dev.first).arg(dev.second));
action->setData(dev.first);
connect(action, &QAction::triggered, this, [this, action]() { doDeviceAutomaticBinding(action->data().toString()); });
added = true;

View File

@@ -88,7 +88,11 @@ ControllerGlobalSettingsWidget::~ControllerGlobalSettingsWidget() = default;
void ControllerGlobalSettingsWidget::addDeviceToList(const QString& identifier, const QString& name)
{
QListWidgetItem* item = new QListWidgetItem();
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
if(identifier.compare(name,Qt::CaseInsensitive) == 0)
item->setText(identifier);
else
item->setText(QStringLiteral("%1: %2").arg(identifier).arg(name));
item->setData(Qt::UserRole, identifier);
m_ui.deviceList->addItem(item);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@
#include "common/MD5Digest.h"
#include "common/Path.h"
#include "common/ScopedGuard.h"
#include "common/SettingsInterface.h"
#include "common/SmallString.h"
#include "common/StringUtil.h"
#include "common/Timer.h"
@@ -439,7 +440,25 @@ bool Achievements::Initialize()
IdentifyGame(VMManager::GetDiscCRC(), VMManager::GetCurrentCRC());
const std::string username = Host::GetBaseStringSettingValue("Achievements", "Username");
const std::string api_token = Host::GetBaseStringSettingValue("Achievements", "Token");
// Check the base settings file to see if the token is defined inside. Move if found.
std::string oldToken = Host::GetBaseStringSettingValue("Achievements", "Token");
if (!oldToken.empty())
{
auto secretsLock = Host::GetSecretsSettingsLock();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->SetStringValue("Achievements", "Token", oldToken.c_str());
secretsInterface->Save();
oldToken.clear();
auto baseLock = Host::GetSettingsLock();
SettingsInterface* baseInterface = Host::Internal::GetBaseSettingsLayer();
baseInterface->DeleteValue("Achievements", "Token");
baseInterface->Save();
}
const std::string api_token = Host::GetStringSettingValue("Achievements", "Token");
if (!username.empty() && !api_token.empty())
{
Console.WriteLn("Achievements: Attempting login with user '%s'...", username.c_str());
@@ -1785,9 +1804,12 @@ void Achievements::ClientLoginWithPasswordCallback(int result, const char* error
// Store configuration.
Host::SetBaseStringSettingValue("Achievements", "Username", params->username);
Host::SetBaseStringSettingValue("Achievements", "Token", user->token);
Host::SetBaseStringSettingValue("Achievements", "LoginTimestamp", fmt::format("{}", std::time(nullptr)).c_str());
Host::CommitBaseSettingChanges();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->SetStringValue("Achievements", "Token", user->token);
secretsInterface->Save();
ShowLoginSuccess(client);
}
@@ -1887,9 +1909,13 @@ void Achievements::Logout()
Console.WriteLn("Achievements: Clearing credentials...");
Host::RemoveBaseSettingValue("Achievements", "Username");
Host::RemoveBaseSettingValue("Achievements", "Token");
Host::RemoveBaseSettingValue("Achievements", "LoginTimestamp");
Host::CommitBaseSettingChanges();
auto secretsLock = Host::GetSecretsSettingsLock();
SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer();
secretsInterface->DeleteValue("Achievements", "Token");
secretsInterface->Save();
}

View File

@@ -10,9 +10,7 @@
std::vector<BreakPoint> CBreakPoints::breakPoints_;
u32 CBreakPoints::breakSkipFirstAtEE_ = 0;
u64 CBreakPoints::breakSkipFirstTicksEE_ = 0;
u32 CBreakPoints::breakSkipFirstAtIop_ = 0;
u64 CBreakPoints::breakSkipFirstTicksIop_ = 0;
std::vector<MemCheck> CBreakPoints::memChecks_;
std::vector<MemCheck*> CBreakPoints::cleanupMemChecks_;
bool CBreakPoints::breakpointTriggered_ = false;
@@ -393,20 +391,18 @@ void CBreakPoints::SetSkipFirst(BreakPointCpu cpu, u32 pc)
if (cpu == BREAKPOINT_EE)
{
breakSkipFirstAtEE_ = standardizeBreakpointAddress(pc);
breakSkipFirstTicksEE_ = r5900Debug.getCycles();
}
else if (cpu == BREAKPOINT_IOP)
{
breakSkipFirstAtIop_ = pc;
breakSkipFirstTicksIop_ = r3000Debug.getCycles();
}
}
u32 CBreakPoints::CheckSkipFirst(BreakPointCpu cpu, u32 cmpPc)
{
if (cpu == BREAKPOINT_EE && breakSkipFirstTicksEE_ == r5900Debug.getCycles())
if (cpu == BREAKPOINT_EE && breakSkipFirstAtEE_ == r5900Debug.getPC())
return breakSkipFirstAtEE_;
else if (cpu == BREAKPOINT_IOP && breakSkipFirstTicksIop_ == r3000Debug.getCycles())
else if (cpu == BREAKPOINT_IOP && breakSkipFirstAtIop_ == r3000Debug.getPC())
return breakSkipFirstAtIop_;
return 0;
}
@@ -414,9 +410,7 @@ u32 CBreakPoints::CheckSkipFirst(BreakPointCpu cpu, u32 cmpPc)
void CBreakPoints::ClearSkipFirst()
{
breakSkipFirstAtEE_ = 0;
breakSkipFirstTicksEE_ = 0;
breakSkipFirstAtIop_ = 0;
breakSkipFirstTicksIop_ = 0;
}
const std::vector<MemCheck> CBreakPoints::GetMemCheckRanges()

View File

@@ -439,7 +439,9 @@ GSRendererType D3D::GetPreferredRenderer()
if (!feature_level.has_value())
return GSRendererType::DX11;
else if (feature_level == D3D_FEATURE_LEVEL_12_0)
return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::DX11;
return check_vulkan_supported() ? GSRendererType::VK : GSRendererType::DX12;
else if (feature_level == D3D_FEATURE_LEVEL_11_1)
return GSRendererType::DX12;
else
return GSRendererType::DX11;
}

View File

@@ -343,12 +343,14 @@ bool GSDevice12::CreateCommandLists()
void GSDevice12::MoveToNextCommandList()
{
m_current_command_list = (m_current_command_list + 1) % NUM_COMMAND_LISTS;
m_current_fence_value++;
const int next_command_list = (m_current_command_list + 1) % NUM_COMMAND_LISTS;
// We may have to wait if this command list hasn't finished on the GPU.
CommandListResources& res = m_command_lists[m_current_command_list];
CommandListResources& res = m_command_lists[next_command_list];
WaitForFence(res.ready_fence_value, false);
m_current_command_list = next_command_list;
m_current_fence_value++;
res.ready_fence_value = m_current_fence_value;
res.init_command_list_used = false;
@@ -2179,13 +2181,13 @@ void GSDevice12::IASetIndexBuffer(const void* index, size_t count)
m_index_stream_buffer.CommitMemory(size);
}
void GSDevice12::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i& scissor)
void GSDevice12::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i& scissor, bool depth_read)
{
GSTexture12* vkRt = static_cast<GSTexture12*>(rt);
GSTexture12* vkDs = static_cast<GSTexture12*>(ds);
pxAssert(vkRt || vkDs);
if (m_current_render_target != vkRt || m_current_depth_target != vkDs)
if (m_current_render_target != vkRt || m_current_depth_target != vkDs || m_current_depth_read_only != depth_read)
{
// framebuffer change
EndRenderPass();
@@ -2212,13 +2214,14 @@ void GSDevice12::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector
m_current_render_target = vkRt;
m_current_depth_target = vkDs;
m_current_depth_read_only = depth_read;
if (!InRenderPass())
{
if (vkRt)
vkRt->TransitionToState(D3D12_RESOURCE_STATE_RENDER_TARGET);
if (vkDs)
vkDs->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
vkDs->TransitionToState(depth_read ? (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) : D3D12_RESOURCE_STATE_DEPTH_WRITE);
}
// This is used to set/initialize the framebuffer for tfx rendering.
@@ -3328,6 +3331,7 @@ void GSDevice12::UnbindTexture(GSTexture12* tex)
{
EndRenderPass();
m_current_depth_target = nullptr;
m_current_depth_read_only = false;
}
}
@@ -3448,7 +3452,7 @@ void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_b
D3D12_RENDER_PASS_DEPTH_STENCIL_DESC ds = {};
if (m_current_depth_target)
{
ds.cpuDescriptor = m_current_depth_target->GetWriteDescriptor();
ds.cpuDescriptor = m_current_depth_read_only ? m_current_depth_target->GetReadDepthViewDescriptor() : m_current_depth_target->GetWriteDescriptor();
ds.DepthEndingAccess.Type = depth_end;
ds.DepthBeginningAccess.Type = depth_begin;
if (depth_begin == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR)
@@ -3468,7 +3472,8 @@ void GSDevice12::BeginRenderPass(D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE color_b
}
GetCommandList()->BeginRenderPass(m_current_render_target ? 1 : 0,
m_current_render_target ? &rt : nullptr, m_current_depth_target ? &ds : nullptr, D3D12_RENDER_PASS_FLAG_NONE);
m_current_render_target ? &rt : nullptr, m_current_depth_target ? &ds : nullptr,
(m_current_depth_target && m_current_depth_read_only) ? (D3D12_RENDER_PASS_FLAG_BIND_READ_ONLY_DEPTH) : D3D12_RENDER_PASS_FLAG_NONE);
}
void GSDevice12::EndRenderPass()
@@ -3550,11 +3555,13 @@ __ri void GSDevice12::ApplyBaseState(u32 flags, ID3D12GraphicsCommandList* cmdli
if (m_current_render_target)
{
cmdlist->OMSetRenderTargets(1, &m_current_render_target->GetWriteDescriptor().cpu_handle, FALSE,
m_current_depth_target ? &m_current_depth_target->GetWriteDescriptor().cpu_handle : nullptr);
m_current_depth_target ?
(m_current_depth_read_only ? &m_current_depth_target->GetReadDepthViewDescriptor().cpu_handle : &m_current_depth_target->GetWriteDescriptor().cpu_handle) :
nullptr);
}
else if (m_current_depth_target)
{
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, &m_current_depth_target->GetWriteDescriptor().cpu_handle);
cmdlist->OMSetRenderTargets(0, nullptr, FALSE, m_current_depth_read_only ? &m_current_depth_target->GetReadDepthViewDescriptor().cpu_handle : &m_current_depth_target->GetWriteDescriptor().cpu_handle);
}
}
}
@@ -3922,15 +3929,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
if (config.blend.constant_enable)
SetBlendConstants(config.blend.constant);
// Depth testing and sampling, bind resource as dsv read only and srv at the same time without the need of a copy.
if (config.tex && config.tex == config.ds)
{
EndRenderPass();
// Transition dsv as read only.
draw_ds->TransitionToState(D3D12_RESOURCE_STATE_DEPTH_READ);
}
// Primitive ID tracking DATE setup.
GSTexture12* date_image = nullptr;
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
@@ -4032,7 +4030,8 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config)
Console.Warning("D3D12: Failed to allocate temp texture for RT copy.");
}
OMSetRenderTargets(draw_rt, draw_ds, config.scissor);
// For depth testing and sampling, use a read only dsv, otherwise use a write dsv
OMSetRenderTargets(draw_rt, draw_ds, config.scissor, config.tex && config.tex == config.ds);
// Begin render pass if new target or out of the area.
if (!m_in_render_pass)

View File

@@ -459,7 +459,7 @@ public:
void PSSetShaderResource(int i, GSTexture* sr, bool check_state, bool feedback = false);
void PSSetSampler(GSHWDrawConfig::SamplerSelector sel);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i& scissor);
void OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i& scissor, bool depth_read = false);
void SetVSConstantBuffer(const GSHWDrawConfig::VSConstantBuffer& cb);
void SetPSConstantBuffer(const GSHWDrawConfig::PSConstantBuffer& cb);
@@ -580,6 +580,7 @@ private:
GSTexture12* m_current_render_target = nullptr;
GSTexture12* m_current_depth_target = nullptr;
bool m_current_depth_read_only = false;
D3D12_VIEWPORT m_viewport = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
GSVector4i m_scissor = GSVector4i::zero();

View File

@@ -17,13 +17,15 @@
GSTexture12::GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<ID3D12Resource> resource_fbl,
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation, const D3D12DescriptorHandle& srv_descriptor,
const D3D12DescriptorHandle& write_descriptor, const D3D12DescriptorHandle& uav_descriptor,
const D3D12DescriptorHandle& fbl_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state)
const D3D12DescriptorHandle& write_descriptor, const D3D12DescriptorHandle& ro_dsv_descriptor,
const D3D12DescriptorHandle& uav_descriptor, const D3D12DescriptorHandle& fbl_descriptor,
WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state)
: m_resource(std::move(resource))
, m_resource_fbl(std::move(resource_fbl))
, m_allocation(std::move(allocation))
, m_srv_descriptor(srv_descriptor)
, m_write_descriptor(write_descriptor)
, m_read_dsv_descriptor(ro_dsv_descriptor)
, m_uav_descriptor(uav_descriptor)
, m_fbl_descriptor(fbl_descriptor)
, m_write_descriptor_type(wdtype)
@@ -58,6 +60,7 @@ void GSTexture12::Destroy(bool defer)
break;
case WriteDescriptorType::DSV:
dev->DeferDescriptorDestruction(dev->GetDSVHeapManager(), &m_write_descriptor);
dev->DeferDescriptorDestruction(dev->GetDSVHeapManager(), &m_read_dsv_descriptor);
break;
case WriteDescriptorType::None:
default:
@@ -87,6 +90,7 @@ void GSTexture12::Destroy(bool defer)
break;
case WriteDescriptorType::DSV:
dev->GetDSVHeapManager().Free(&m_write_descriptor);
dev->GetDSVHeapManager().Free(&m_read_dsv_descriptor);
break;
case WriteDescriptorType::None:
default:
@@ -237,7 +241,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
}
}
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor, fbl_descriptor;
D3D12DescriptorHandle srv_descriptor, write_descriptor, ro_dsv_descriptor, uav_descriptor, fbl_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
@@ -261,11 +265,17 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
case Type::DepthStencil:
{
write_descriptor_type = WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor, false))
{
dev->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
if (!CreateDSVDescriptor(resource.get(), dsv_format, &ro_dsv_descriptor, true))
{
dev->GetDSVHeapManager().Free(&write_descriptor);
dev->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
}
break;
@@ -281,6 +291,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
dev->GetRTVHeapManager().Free(&write_descriptor);
break;
case WriteDescriptorType::DSV:
dev->GetDSVHeapManager().Free(&ro_dsv_descriptor);
dev->GetDSVHeapManager().Free(&write_descriptor);
break;
default:
@@ -301,6 +312,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
dev->GetRTVHeapManager().Free(&write_descriptor);
break;
case WriteDescriptorType::DSV:
dev->GetDSVHeapManager().Free(&ro_dsv_descriptor);
dev->GetDSVHeapManager().Free(&write_descriptor);
break;
default:
@@ -313,7 +325,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
return std::unique_ptr<GSTexture12>(
new GSTexture12(type, format, width, height, levels, dxgi_format, std::move(resource), std::move(resource_fbl), std::move(allocation),
srv_descriptor, write_descriptor, uav_descriptor, fbl_descriptor, write_descriptor_type, state));
srv_descriptor, write_descriptor, ro_dsv_descriptor, uav_descriptor, fbl_descriptor, write_descriptor_type, state));
}
std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resource> resource, Type type, Format format,
@@ -322,7 +334,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resou
{
const D3D12_RESOURCE_DESC desc = resource->GetDesc();
D3D12DescriptorHandle srv_descriptor, write_descriptor, uav_descriptor;
D3D12DescriptorHandle srv_descriptor, write_descriptor, ro_dsv_descriptor, uav_descriptor;
WriteDescriptorType write_descriptor_type = WriteDescriptorType::None;
if (srv_format != DXGI_FORMAT_UNKNOWN)
{
@@ -342,11 +354,17 @@ std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resou
else if (type == Type::DepthStencil)
{
write_descriptor_type = WriteDescriptorType::DSV;
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor))
if (!CreateDSVDescriptor(resource.get(), dsv_format, &write_descriptor, false))
{
GSDevice12::GetInstance()->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
if (!CreateDSVDescriptor(resource.get(), dsv_format, &ro_dsv_descriptor, true))
{
GSDevice12::GetInstance()->GetDSVHeapManager().Free(&write_descriptor);
GSDevice12::GetInstance()->GetDescriptorHeapManager().Free(&srv_descriptor);
return {};
}
}
if (uav_format != DXGI_FORMAT_UNKNOWN)
@@ -359,6 +377,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resou
GSDevice12::GetInstance()->GetRTVHeapManager().Free(&write_descriptor);
break;
case WriteDescriptorType::DSV:
GSDevice12::GetInstance()->GetDSVHeapManager().Free(&ro_dsv_descriptor);
GSDevice12::GetInstance()->GetDSVHeapManager().Free(&write_descriptor);
break;
default:
@@ -371,7 +390,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Adopt(wil::com_ptr_nothrow<ID3D12Resou
}
return std::unique_ptr<GSTexture12>(new GSTexture12(type, format, static_cast<u32>(desc.Width), desc.Height,
desc.MipLevels, desc.Format, std::move(resource), {}, {}, srv_descriptor, write_descriptor, uav_descriptor,
desc.MipLevels, desc.Format, std::move(resource), {}, {}, srv_descriptor, write_descriptor, {}, uav_descriptor,
{}, write_descriptor_type, resource_state));
}
@@ -405,7 +424,7 @@ bool GSTexture12::CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT form
return true;
}
bool GSTexture12::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh)
bool GSTexture12::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh, bool read_only)
{
if (!GSDevice12::GetInstance()->GetDSVHeapManager().Allocate(dh))
{
@@ -413,7 +432,7 @@ bool GSTexture12::CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT form
return false;
}
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, D3D12_DSV_FLAG_NONE};
const D3D12_DEPTH_STENCIL_VIEW_DESC desc = {format, D3D12_DSV_DIMENSION_TEXTURE2D, read_only ? D3D12_DSV_FLAG_READ_ONLY_DEPTH : D3D12_DSV_FLAG_NONE };
GSDevice12::GetInstance()->GetDevice()->CreateDepthStencilView(resource, &desc, dh->cpu_handle);
return true;
}
@@ -708,7 +727,36 @@ void GSTexture12::TransitionToState(ID3D12GraphicsCommandList* cmdlist, D3D12_RE
if (m_resource_state == state)
return;
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_resource_state, state);
// Read only depth requires special handling as we might want to write stencil.
// Also batch the transition barriers as per recommendation from docs.
if (state == (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE))
{
// Transition to read depth/write stencil
const D3D12_RESOURCE_BARRIER barriers[2] = {
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 0, m_resource_state, (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)}}},
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 1, m_resource_state, D3D12_RESOURCE_STATE_DEPTH_WRITE}}},
};
cmdlist->ResourceBarrier(m_resource_state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
}
else if (m_resource_state == (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE))
{
// Transition from read depth/write stencil
const D3D12_RESOURCE_BARRIER barriers[2] = {
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 0, (D3D12_RESOURCE_STATE_DEPTH_READ | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE), state}}},
{D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_FLAG_NONE,
{{m_resource.get(), 1, D3D12_RESOURCE_STATE_DEPTH_WRITE, state}}},
};
cmdlist->ResourceBarrier(state == D3D12_RESOURCE_STATE_DEPTH_WRITE ? 1 : 2, barriers);
}
else
{
// Normal transition
TransitionSubresourceToState(cmdlist, D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, m_resource_state, state);
}
m_resource_state = state;
}

View File

@@ -30,6 +30,7 @@ public:
__fi const D3D12DescriptorHandle& GetSRVDescriptor() const { return m_srv_descriptor; }
__fi const D3D12DescriptorHandle& GetWriteDescriptor() const { return m_write_descriptor; }
__fi const D3D12DescriptorHandle& GetReadDepthViewDescriptor() const { return m_read_dsv_descriptor; }
__fi const D3D12DescriptorHandle& GetUAVDescriptor() const { return m_uav_descriptor; }
__fi const D3D12DescriptorHandle& GetFBLDescriptor() const { return m_fbl_descriptor; }
__fi D3D12_RESOURCE_STATES GetResourceState() const { return m_resource_state; }
@@ -72,13 +73,14 @@ private:
GSTexture12(Type type, Format format, int width, int height, int levels, DXGI_FORMAT dxgi_format,
wil::com_ptr_nothrow<ID3D12Resource> resource, wil::com_ptr_nothrow<ID3D12Resource> resource_fbl,
wil::com_ptr_nothrow<D3D12MA::Allocation> allocation, const D3D12DescriptorHandle& srv_descriptor,
const D3D12DescriptorHandle& write_descriptor, const D3D12DescriptorHandle& uav_descriptor,
const D3D12DescriptorHandle& fbl_descriptor, WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state);
const D3D12DescriptorHandle& write_descriptor, const D3D12DescriptorHandle& ro_dsv_descriptor,
const D3D12DescriptorHandle& uav_descriptor, const D3D12DescriptorHandle& fbl_descriptor,
WriteDescriptorType wdtype, D3D12_RESOURCE_STATES resource_state);
static bool CreateSRVDescriptor(
ID3D12Resource* resource, u32 levels, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateRTVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
static bool CreateDSVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh, bool read_only);
static bool CreateUAVDescriptor(ID3D12Resource* resource, DXGI_FORMAT format, D3D12DescriptorHandle* dh);
ID3D12GraphicsCommandList* GetCommandBufferForUpdate();
@@ -91,6 +93,7 @@ private:
D3D12DescriptorHandle m_srv_descriptor = {};
D3D12DescriptorHandle m_write_descriptor = {};
D3D12DescriptorHandle m_read_dsv_descriptor = {};
D3D12DescriptorHandle m_uav_descriptor = {};
D3D12DescriptorHandle m_fbl_descriptor = {};
WriteDescriptorType m_write_descriptor_type = WriteDescriptorType::None;

View File

@@ -26,6 +26,7 @@ namespace Host
const std::string_view context, const std::string_view msg);
static std::mutex s_settings_mutex;
static std::mutex s_secrets_settings_mutex;
static LayeredSettingsInterface s_layered_settings_interface;
static constexpr u32 TRANSLATION_STRING_CACHE_SIZE = 4 * 1024 * 1024;
@@ -164,6 +165,11 @@ std::unique_lock<std::mutex> Host::GetSettingsLock()
return std::unique_lock<std::mutex>(s_settings_mutex);
}
std::unique_lock<std::mutex> Host::GetSecretsSettingsLock()
{
return std::unique_lock<std::mutex>(s_secrets_settings_mutex);
}
SettingsInterface* Host::GetSettingsInterface()
{
return &s_layered_settings_interface;
@@ -352,6 +358,11 @@ SettingsInterface* Host::Internal::GetBaseSettingsLayer()
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE);
}
SettingsInterface* Host::Internal::GetSecretsSettingsLayer()
{
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_SECRETS);
}
SettingsInterface* Host::Internal::GetGameSettingsLayer()
{
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME);
@@ -365,10 +376,17 @@ SettingsInterface* Host::Internal::GetInputSettingsLayer()
void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif)
{
pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr,
"Base layer has not been set");
"Base layer has already been set");
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif);
}
void Host::Internal::SetSecretsSettingsLayer(SettingsInterface* sif)
{
pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_SECRETS) == nullptr,
"Secrets layer has already been set");
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_SECRETS, sif);
}
void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock<std::mutex>& settings_lock)
{
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif);

View File

@@ -134,6 +134,8 @@ namespace Host
/// Direct access to settings interface. Must hold the lock when calling GetSettingsInterface() and while using it.
std::unique_lock<std::mutex> GetSettingsLock();
/// Ditto for secrets file.
std::unique_lock<std::mutex> GetSecretsSettingsLock();
SettingsInterface* GetSettingsInterface();
/// Sets host-specific default settings.
@@ -147,6 +149,9 @@ namespace Host
/// Retrieves the base settings layer. Must call with lock held.
SettingsInterface* GetBaseSettingsLayer();
/// Retrieves the base settings layer. Must call with lock held.
SettingsInterface* GetSecretsSettingsLayer();
/// Retrieves the game settings layer, if present. Must call with lock held.
SettingsInterface* GetGameSettingsLayer();
@@ -156,6 +161,9 @@ namespace Host
/// Sets the base settings layer. Should be called by the host at initialization time.
void SetBaseSettingsLayer(SettingsInterface* sif);
/// Sets the secrets settings layer. Should follow call to SetBaseSettingsLayer.
void SetSecretsSettingsLayer(SettingsInterface* sif);
/// Sets the game settings layer. Called by VMManager when the game changes.
void SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock<std::mutex>& settings_lock);

View File

@@ -3458,8 +3458,11 @@ void FullscreenUI::StartAutomaticBinding(u32 port)
names.reserve(devices.size());
for (auto& [name, display_name] : devices)
{
if(!StringUtil::compareNoCase(name, display_name))
options.emplace_back(fmt::format("{}: {}", name, display_name), false);
else
options.emplace_back(std::move(display_name), false);
names.push_back(std::move(name));
options.emplace_back(std::move(display_name), false);
}
OpenChoiceDialog(FSUI_CSTR("Select Device"), false, std::move(options),
[port, names = std::move(names)](s32 index, const std::string& title, bool checked) {

View File

@@ -15,6 +15,7 @@ public:
LAYER_CMDLINE,
LAYER_GAME,
LAYER_INPUT,
LAYER_SECRETS,
LAYER_BASE,
NUM_LAYERS
};