Formatting: Apply AlignWithSpaces
Some checks are pending
🐧 Linux Builds / AppImage (push) Waiting to run
🐧 Linux Builds / Flatpak (push) Waiting to run
🍎 MacOS Builds / Defaults (push) Waiting to run
🖥️ Windows Builds / Lint VS Project Files (push) Waiting to run
🖥️ Windows Builds / SSE4 (push) Blocked by required conditions
🖥️ Windows Builds / AVX2 (push) Blocked by required conditions
🖥️ Windows Builds / CMake (push) Waiting to run

This commit is contained in:
TellowKrinkle 2025-06-12 23:16:13 -05:00 committed by lightningterror
parent c5820a4f54
commit 8fd91cb7df
46 changed files with 428 additions and 443 deletions

View File

@ -600,7 +600,7 @@ bool SmallStringBase::starts_with(const char* str, bool case_sensitive) const
return false;
return (case_sensitive) ? (std::strncmp(str, m_buffer, other_length) == 0) :
(CASE_N_COMPARE(str, m_buffer, other_length) == 0);
(CASE_N_COMPARE(str, m_buffer, other_length) == 0);
}
bool SmallStringBase::starts_with(const SmallStringBase& str, bool case_sensitive) const
@ -610,7 +610,7 @@ bool SmallStringBase::starts_with(const SmallStringBase& str, bool case_sensitiv
return false;
return (case_sensitive) ? (std::strncmp(str.m_buffer, m_buffer, other_length) == 0) :
(CASE_N_COMPARE(str.m_buffer, m_buffer, other_length) == 0);
(CASE_N_COMPARE(str.m_buffer, m_buffer, other_length) == 0);
}
bool SmallStringBase::starts_with(const std::string_view str, bool case_sensitive) const
@ -620,7 +620,7 @@ bool SmallStringBase::starts_with(const std::string_view str, bool case_sensitiv
return false;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
}
bool SmallStringBase::starts_with(const std::string& str, bool case_sensitive) const
@ -630,7 +630,7 @@ bool SmallStringBase::starts_with(const std::string& str, bool case_sensitive) c
return false;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
(CASE_N_COMPARE(str.data(), m_buffer, other_length) == 0);
}
bool SmallStringBase::ends_with(const char* str, bool case_sensitive) const
@ -641,7 +641,7 @@ bool SmallStringBase::ends_with(const char* str, bool case_sensitive) const
u32 start_offset = m_length - other_length;
return (case_sensitive) ? (std::strncmp(str, m_buffer + start_offset, other_length) == 0) :
(CASE_N_COMPARE(str, m_buffer + start_offset, other_length) == 0);
(CASE_N_COMPARE(str, m_buffer + start_offset, other_length) == 0);
}
bool SmallStringBase::ends_with(const SmallStringBase& str, bool case_sensitive) const
@ -652,7 +652,7 @@ bool SmallStringBase::ends_with(const SmallStringBase& str, bool case_sensitive)
const u32 start_offset = m_length - other_length;
return (case_sensitive) ? (std::strncmp(str.m_buffer, m_buffer + start_offset, other_length) == 0) :
(CASE_N_COMPARE(str.m_buffer, m_buffer + start_offset, other_length) == 0);
(CASE_N_COMPARE(str.m_buffer, m_buffer + start_offset, other_length) == 0);
}
bool SmallStringBase::ends_with(const std::string_view str, bool case_sensitive) const
@ -663,7 +663,7 @@ bool SmallStringBase::ends_with(const std::string_view str, bool case_sensitive)
const u32 start_offset = m_length - other_length;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer + start_offset, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
}
bool SmallStringBase::ends_with(const std::string& str, bool case_sensitive) const
@ -674,7 +674,7 @@ bool SmallStringBase::ends_with(const std::string& str, bool case_sensitive) con
const u32 start_offset = m_length - other_length;
return (case_sensitive) ? (std::strncmp(str.data(), m_buffer + start_offset, other_length) == 0) :
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
(CASE_N_COMPARE(str.data(), m_buffer + start_offset, other_length) == 0);
}
void SmallStringBase::clear()

View File

@ -47,16 +47,16 @@ AboutDialog::AboutDialog(QWidget* parent)
m_ui.links->setTextInteractionFlags(Qt::TextBrowserInteraction);
m_ui.links->setText(QStringLiteral(
R"(<a href="%1">%2</a> | <a href="%3">%4</a> | <a href="%5">%6</a> | <a href="%7">%8</a> | <a href="%9">%10</a>)")
.arg(getWebsiteUrl())
.arg(tr("Website"))
.arg(getSupportForumsUrl())
.arg(tr("Support Forums"))
.arg(getGitHubRepositoryUrl())
.arg(tr("GitHub Repository"))
.arg(getLicenseUrl())
.arg(tr("License"))
.arg(getThirdPartyLicensesUrl())
.arg(tr("Third-Party Licenses")));
.arg(getWebsiteUrl())
.arg(tr("Website"))
.arg(getSupportForumsUrl())
.arg(tr("Support Forums"))
.arg(getGitHubRepositoryUrl())
.arg(tr("GitHub Repository"))
.arg(getLicenseUrl())
.arg(tr("License"))
.arg(getThirdPartyLicensesUrl())
.arg(tr("Third-Party Licenses")));
connect(m_ui.links, &QLabel::linkActivated, this, &AboutDialog::linksLinkActivated);
connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &QDialog::close);

View File

@ -874,10 +874,10 @@ inline QString DisassemblyView::DisassemblyStringFromAddress(u32 address, QFont
}
lineString = lineString.leftJustified(4, ' ') // Address / symbol
.arg(line.name.c_str())
.arg(line.params.c_str()) // opcode + arguments
.arg(isConditional ? (isConditionalMet ? "# true" : "# false") : "")
.arg(isCurrentPC ? "<--" : "");
.arg(line.name.c_str())
.arg(line.params.c_str()) // opcode + arguments
.arg(isConditional ? (isConditionalMet ? "# true" : "# false") : "")
.arg(isCurrentPC ? "<--" : "");
return lineString;
}

View File

@ -1129,8 +1129,8 @@ bool MainWindow::shouldHideMainWindow() const
{
// NOTE: We can't use isRenderingToMain() here, because this happens post-fullscreen-switch.
return (Host::GetBoolSettingValue("UI", "HideMainWindowWhenRunning", false) && !g_emu_thread->shouldRenderToMain()) ||
(g_emu_thread->shouldRenderToMain() && (isRenderingFullscreen() || m_is_temporarily_windowed)) ||
Host::InNoGUIMode();
(g_emu_thread->shouldRenderToMain() && (isRenderingFullscreen() || m_is_temporarily_windowed)) ||
Host::InNoGUIMode();
}
bool MainWindow::shouldMouseLock() const
@ -1142,8 +1142,8 @@ bool MainWindow::shouldMouseLock() const
return false;
bool windowsHidden = (!g_debugger_window || g_debugger_window->isHidden()) &&
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
(!m_settings_window || m_settings_window->isHidden());
(!m_controller_settings_window || m_controller_settings_window->isHidden()) &&
(!m_settings_window || m_settings_window->isHidden());
return windowsHidden && (isActiveWindow() || isRenderingFullscreen());
}

View File

@ -1000,21 +1000,21 @@ void EmuThread::updatePerformanceMetrics(bool force)
if (THREAD_VU1)
{
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | VU: %5% | GS: %6%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetVUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
else
{
gs_stat = tr("Slot: %1 | Volume: %2% | %3 | EE: %4% | GS: %5%")
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
.arg(SaveStateSelectorUI::GetCurrentSlot())
.arg(SPU2::GetOutputVolume())
.arg(gs_stat_str.c_str())
.arg(PerformanceMetrics::GetCPUThreadUsage(), 0, 'f', 0)
.arg(PerformanceMetrics::GetGSThreadUsage(), 0, 'f', 0);
}
QMetaObject::invokeMethod(g_main_window->getStatusVerboseWidget(), "setText", Qt::QueuedConnection, Q_ARG(const QString&, gs_stat));
@ -1129,9 +1129,9 @@ void Host::OnAchievementsRefreshed()
game_id = Achievements::GetGameID();
game_info = qApp
->translate("EmuThread", "Game: %1 (%2)\n")
.arg(QString::fromStdString(Achievements::GetGameTitle()))
.arg(game_id);
->translate("EmuThread", "Game: %1 (%2)\n")
.arg(QString::fromStdString(Achievements::GetGameTitle()))
.arg(game_id);
const std::string& rich_presence_string = Achievements::GetRichPresenceString();
if (!rich_presence_string.empty())
@ -1181,7 +1181,7 @@ void Host::OpenHostFileSelectorAsync(std::string_view title, bool select_directo
if (!filters.empty())
{
filters_str.append(QStringLiteral("All File Types (%1)")
.arg(QString::fromStdString(StringUtil::JoinString(filters.begin(), filters.end(), " "))));
.arg(QString::fromStdString(StringUtil::JoinString(filters.begin(), filters.end(), " "))));
for (const std::string& filter : filters)
{
filters_str.append(

View File

@ -90,9 +90,7 @@ namespace QtUtils
const int min_column_width = header->minimumSectionSize();
const int scrollbar_width = ((view->verticalScrollBar() && view->verticalScrollBar()->isVisible()) ||
view->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn) ?
view->verticalScrollBar()->width() :
0;
view->verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn) ? view->verticalScrollBar()->width() : 0;
int num_flex_items = 0;
int total_width = 0;
int column_index = 0;

View File

@ -242,8 +242,8 @@ namespace SettingWidgetBinder
static std::optional<QString> getNullableStringValue(const QCheckBox* widget)
{
return (widget->checkState() == Qt::PartiallyChecked) ?
std::nullopt :
std::optional<QString>(widget->isChecked() ? QStringLiteral("1") : QStringLiteral("0"));
std::nullopt :
std::optional<QString>(widget->isChecked() ? QStringLiteral("1") : QStringLiteral("0"));
}
static void setNullableStringValue(QCheckBox* widget, std::optional<QString> value)
{

View File

@ -40,7 +40,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.notificationPosition, "Achievements", "NotificationPosition", static_cast<int>(OsdOverlayPos::TopLeft));
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.encoreMode, "Achievements", "EncoreMode", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.spectatorMode, "Achievements", "SpectatorMode", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.unofficialAchievements, "Achievements", "UnofficialTestMode",false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.unofficialAchievements, "Achievements", "UnofficialTestMode", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.achievementNotificationsDuration, "Achievements", "NotificationsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_NOTIFICATION_DURATION);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.leaderboardNotificationsDuration, "Achievements", "LeaderboardsDuration", Pcsx2Config::AchievementsOptions::DEFAULT_LEADERBOARD_DURATION);
@ -57,7 +57,7 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* dialog, QWi
dialog->registerWidgetHelp(m_ui.overlays, tr("Enable In-Game Overlays"), tr("Checked"), tr("Shows icons in the lower-right corner of the screen when a challenge/primed achievement is active."));
dialog->registerWidgetHelp(m_ui.overlayPosition, tr("Overlay Position"), tr("Bottom Right"), tr("Determines where achievement overlays are positioned on the screen."));
dialog->registerWidgetHelp(m_ui.notificationPosition, tr("Notification Position"), tr("Top Left"), tr("Determines where achievement notification popups are positioned on the screen."));
dialog->registerWidgetHelp(m_ui.encoreMode, tr("Enable Encore Mode"), tr("Unchecked"),tr("When enabled, each session will behave as if no achievements have been unlocked."));
dialog->registerWidgetHelp(m_ui.encoreMode, tr("Enable Encore Mode"), tr("Unchecked"), tr("When enabled, each session will behave as if no achievements have been unlocked."));
dialog->registerWidgetHelp(m_ui.spectatorMode, tr("Enable Spectator Mode"), tr("Unchecked"), tr("When enabled, PCSX2 will assume all achievements are locked and not send any unlock notifications to the server."));
dialog->registerWidgetHelp(m_ui.unofficialAchievements, tr("Test Unofficial Achievements"), tr("Unchecked"), tr("When enabled, PCSX2 will list achievements from unofficial sets. Please note that these achievements are not tracked by RetroAchievements, so they unlock every time."));
@ -211,8 +211,8 @@ void AchievementSettingsWidget::updateLoginState()
StringUtil::FromChars<u64>(Host::GetBaseStringSettingValue("Achievements", "LoginTimestamp", "0")).value_or(0);
const QDateTime login_timestamp(QDateTime::fromSecsSinceEpoch(static_cast<qint64>(login_unix_timestamp)));
m_ui.loginStatus->setText(tr("Username: %1\nLogin token generated on %2.")
.arg(QString::fromStdString(username))
.arg(login_timestamp.toString(Qt::TextDate)));
.arg(QString::fromStdString(username))
.arg(login_timestamp.toString(Qt::TextDate)));
m_ui.loginButton->setText(tr("Logout"));
}
else

View File

@ -54,7 +54,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(SettingsWindow* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.patches, "EmuCore", "EnablePatches", true);
dialog->registerWidgetHelp(m_ui.savestateSelector, tr("Use Save State Selector"), tr("Checked"),
tr("Show a save state selector UI when switching slots instead of showing a notification bubble."));
tr("Show a save state selector UI when switching slots instead of showing a notification bubble."));
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.savestateCompressionMethod, "EmuCore", "SavestateCompressionType", static_cast<int>(SavestateCompressionMethod::Zstandard));
@ -220,6 +220,6 @@ void AdvancedSettingsWidget::setClampingMode(int vunum, int index)
void AdvancedSettingsWidget::onSavestateCompressionTypeChanged()
{
const bool uncompressed = (m_dialog->getEffectiveIntValue("EmuCore", "SavestateCompressionType", static_cast<int>(SavestateCompressionMethod::Zstandard)) ==
static_cast<int>(SavestateCompressionMethod::Uncompressed));
static_cast<int>(SavestateCompressionMethod::Uncompressed));
m_ui.savestateCompressionLevel->setDisabled(uncompressed);
}
}

View File

@ -160,20 +160,20 @@ void AudioSettingsWidget::onSyncModeChanged()
{
const Pcsx2Config::SPU2Options::SPU2SyncMode sync_mode =
Pcsx2Config::SPU2Options::ParseSyncMode(
m_dialog
->getEffectiveStringValue("SPU2/Output", "SyncMode",
Pcsx2Config::SPU2Options::GetSyncModeName(Pcsx2Config::SPU2Options::DEFAULT_SYNC_MODE))
.c_str())
.value_or(Pcsx2Config::SPU2Options::DEFAULT_SYNC_MODE);
m_dialog->getEffectiveStringValue("SPU2/Output", "SyncMode",
Pcsx2Config::SPU2Options::GetSyncModeName(Pcsx2Config::SPU2Options::DEFAULT_SYNC_MODE)
).c_str()
).value_or(Pcsx2Config::SPU2Options::DEFAULT_SYNC_MODE);
m_ui.stretchSettings->setEnabled(sync_mode == Pcsx2Config::SPU2Options::SPU2SyncMode::TimeStretch);
}
AudioBackend AudioSettingsWidget::getEffectiveBackend() const
{
return AudioStream::ParseBackendName(m_dialog->getEffectiveStringValue("SPU2/Output", "Backend",
AudioStream::GetBackendName(Pcsx2Config::SPU2Options::DEFAULT_BACKEND))
.c_str())
.value_or(Pcsx2Config::SPU2Options::DEFAULT_BACKEND);
return AudioStream::ParseBackendName(
m_dialog->getEffectiveStringValue("SPU2/Output", "Backend",
AudioStream::GetBackendName(Pcsx2Config::SPU2Options::DEFAULT_BACKEND)
).c_str()
).value_or(Pcsx2Config::SPU2Options::DEFAULT_BACKEND);
}
void AudioSettingsWidget::updateDriverNames()
@ -263,17 +263,17 @@ void AudioSettingsWidget::updateLatencyLabel()
if (expand_buffer_ms > 0)
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms expand + %4 ms output)")
.arg(config_buffer_ms + expand_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(expand_buffer_ms)
.arg(output_latency_ms));
.arg(config_buffer_ms + expand_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(expand_buffer_ms)
.arg(output_latency_ms));
}
else
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms buffer + %3 ms output)")
.arg(config_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(output_latency_ms));
.arg(config_buffer_ms + output_latency_ms)
.arg(config_buffer_ms)
.arg(output_latency_ms));
}
}
else
@ -281,8 +281,8 @@ void AudioSettingsWidget::updateLatencyLabel()
if (expand_buffer_ms > 0)
{
m_ui.bufferingLabel->setText(tr("Maximum Latency: %1 ms (%2 ms expand, minimum output latency unknown)")
.arg(expand_buffer_ms + config_buffer_ms)
.arg(expand_buffer_ms));
.arg(expand_buffer_ms + config_buffer_ms)
.arg(expand_buffer_ms));
}
else
{

View File

@ -206,7 +206,7 @@ void ControllerSettingsWindow::onRenameProfileClicked()
{
std::string game_settings_path(game_settings.FileName.c_str());
std::unique_ptr<INISettingsInterface> update_sif(std::make_unique<INISettingsInterface>(std::move(game_settings_path)));
update_sif->Load();
if (!old_profile_name.compare(update_sif->GetStringValue("EmuCore", "InputProfileName")))
@ -458,9 +458,9 @@ void ControllerSettingsWindow::createWidgets()
QListWidgetItem* item = new QListWidgetItem();
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
item->setText(mtap_enabled[port] ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setText(mtap_enabled[port] ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name))
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
: tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(m_port_bindings[global_slot]->getIcon());
item->setData(Qt::UserRole, QVariant(global_slot));
m_ui.settingsCategory->addItem(item);
@ -514,9 +514,9 @@ void ControllerSettingsWindow::updateListDescription(u32 global_slot, Controller
const QString display_name = QString::fromUtf8(ci ? ci->GetLocalizedName() : "Unknown");
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name)) :
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setText(mtap_enabled ? (tr("Controller Port %1%2\n%3").arg(port + 1).arg(s_mtap_slot_names[slot]).arg(display_name))
//: Controller Port is an official term from Sony. Find the official translation for your language inside the console's manual.
: tr("Controller Port %1\n%2").arg(port + 1).arg(display_name));
item->setIcon(widget->getIcon());
break;
}

View File

@ -290,7 +290,7 @@ void DEV9SettingsWidget::onEthDeviceChanged(int index)
void DEV9SettingsWidget::onEthDHCPInterceptChanged(Qt::CheckState state)
{
const bool enabled = (state == Qt::CheckState::PartiallyChecked ? Host::GetBaseBoolSettingValue("DEV9/Eth", "InterceptDHCP", false) : state) ||
((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::DHCP_ForcedOn);
((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::DHCP_ForcedOn);
// clang-format off
const bool ipOverride = (m_adapter_options & AdapterOptions::DHCP_OverrideIP) == AdapterOptions::DHCP_OverrideIP;

View File

@ -55,11 +55,11 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
connect(m_ui.manuallySetRealTimeClock, &QCheckBox::checkStateChanged, this, &EmulationSettingsWidget::onManuallySetRealTimeClockChanged);
EmulationSettingsWidget::onManuallySetRealTimeClockChanged();
m_ui.eeCycleRate->insertItem(
0, tr("Use Global Setting [%1]")
.arg(m_ui.eeCycleRate->itemText(
std::clamp(Host::GetBaseIntSettingValue("EmuCore/Speedhacks", "EECycleRate", DEFAULT_EE_CYCLE_RATE) - MINIMUM_EE_CYCLE_RATE,
0, MAXIMUM_EE_CYCLE_RATE - MINIMUM_EE_CYCLE_RATE))));
m_ui.eeCycleRate->insertItem(0,
tr("Use Global Setting [%1]")
.arg(m_ui.eeCycleRate->itemText(
std::clamp(Host::GetBaseIntSettingValue("EmuCore/Speedhacks", "EECycleRate", DEFAULT_EE_CYCLE_RATE) - MINIMUM_EE_CYCLE_RATE,
0, MAXIMUM_EE_CYCLE_RATE - MINIMUM_EE_CYCLE_RATE))));
// Disable cheats, use the cheats panel instead (move fastcvd up in its spot).
const int count = m_ui.systemSettingsLayout->count();
@ -92,9 +92,9 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
const std::optional<int> cycle_rate =
m_dialog->getIntValue("EmuCore/Speedhacks", "EECycleRate", sif ? std::nullopt : std::optional<int>(DEFAULT_EE_CYCLE_RATE));
m_ui.eeCycleRate->setCurrentIndex(cycle_rate.has_value() ? (std::clamp(cycle_rate.value(), MINIMUM_EE_CYCLE_RATE, MAXIMUM_EE_CYCLE_RATE) +
(0 - MINIMUM_EE_CYCLE_RATE) + static_cast<int>(m_dialog->isPerGameSettings())) :
0);
m_ui.eeCycleRate->setCurrentIndex(cycle_rate.has_value() ? (std::clamp(cycle_rate.value(), MINIMUM_EE_CYCLE_RATE, MAXIMUM_EE_CYCLE_RATE)
+ (0 - MINIMUM_EE_CYCLE_RATE) + static_cast<int>(m_dialog->isPerGameSettings()))
: 0);
connect(m_ui.eeCycleRate, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int index) {
std::optional<int> value;
if (!m_dialog->isPerGameSettings() || index > 0)
@ -164,9 +164,9 @@ EmulationSettingsWidget::EmulationSettingsWidget(SettingsWindow* dialog, QWidget
tr("Manually set a real-time clock to use for the virtual PlayStation 2 instead of using your OS' system clock."));
dialog->registerWidgetHelp(m_ui.rtcDateTime, tr("Real-Time Clock"), tr("Current date and time"),
tr("Real-time clock (RTC) used by the virtual PlayStation 2. Date format is the same as the one used by your OS. "
"This time is only applied upon booting the PS2; changing it while in-game will have no effect. "
"NOTE: This assumes you have your PS2 set to the default timezone of GMT+0 and default DST of Summer Time. "
"Some games require an RTC date/time set after their release date."));
"This time is only applied upon booting the PS2; changing it while in-game will have no effect. "
"NOTE: This assumes you have your PS2 set to the default timezone of GMT+0 and default DST of Summer Time. "
"Some games require an RTC date/time set after their release date."));
updateOptimalFramePacing();
updateUseVSyncForTimingEnabled();

View File

@ -205,7 +205,7 @@ void GameCheatSettingsWidget::reloadList()
{
u32 num_unlabelled_codes = 0;
bool showAllCRCS = m_ui.allCRCsCheckbox->isChecked();
m_patches = Patch::GetPatchInfo(m_dialog->getSerial(), m_dialog->getDiscCRC(), true, showAllCRCS, & num_unlabelled_codes);
m_patches = Patch::GetPatchInfo(m_dialog->getSerial(), m_dialog->getDiscCRC(), true, showAllCRCS, &num_unlabelled_codes);
m_enabled_patches =
m_dialog->getSettingsInterface()->GetStringList(Patch::CHEATS_CONFIG_SECTION, Patch::PATCH_ENABLE_CONFIG_KEY);

View File

@ -340,15 +340,15 @@ void GameSummaryWidget::onVerifyClicked()
if (!hentry->version.empty())
{
setVerifyResult(tr("Verified as %1 [%2] (Version %3).")
.arg(QString::fromStdString(hentry->name))
.arg(QString::fromStdString(hentry->serial))
.arg(QString::fromStdString(hentry->version)));
.arg(QString::fromStdString(hentry->name))
.arg(QString::fromStdString(hentry->serial))
.arg(QString::fromStdString(hentry->version)));
}
else
{
setVerifyResult(tr("Verified as %1 [%2].")
.arg(QString::fromStdString(hentry->name))
.arg(QString::fromStdString(hentry->serial)));
.arg(QString::fromStdString(hentry->name))
.arg(QString::fromStdString(hentry->serial)));
}
}
else

View File

@ -1280,8 +1280,8 @@ void GraphicsSettingsWidget::populateUpscaleMultipliers(u32 max_upscale_multipli
m_ui.upscaleMultiplier->clear();
const u32 max_shown_multiplier = m_ui.extendedUpscales && m_ui.extendedUpscales->checkState() == Qt::Checked ?
max_upscale_multiplier :
std::min(max_upscale_multiplier, max_non_advanced_multiplier);
max_upscale_multiplier :
std::min(max_upscale_multiplier, max_non_advanced_multiplier);
for (const auto& [name, value] : templates)
{
if (value > max_shown_multiplier)

View File

@ -260,7 +260,7 @@ void InputBindingWidget::clearBinding()
void InputBindingWidget::reloadBinding()
{
m_bindings_settings = m_sif ? m_sif->GetStringList(m_section_name.c_str(), m_key_name.c_str()) :
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
Host::GetBaseStringListSetting(m_section_name.c_str(), m_key_name.c_str());
m_bindings_ui.clear();
m_bindings_ui.reserve(m_bindings_settings.size());

View File

@ -250,7 +250,7 @@ void MemoryCardConvertDialog::ConvertCard()
baseName.replace(extensionPos, 4, "");
// Add _converted to the end of it
baseName.append("_converted");
size_t num = 0;
QString destName = baseName;
destName.append(".ps2");
@ -322,5 +322,5 @@ void MemoryCardConvertDialog::SetType_Folder()
void MemoryCardConvertDialog::FileOpenError(const QString errmsg)
{
QMessageBox::critical(this, tr("Cannot Convert Memory Card"),tr("There was an error when accessing the memory card directory. Error message: %0").arg(errmsg));
QMessageBox::critical(this, tr("Cannot Convert Memory Card"), tr("There was an error when accessing the memory card directory. Error message: %0").arg(errmsg));
}

View File

@ -42,7 +42,7 @@ private:
void SetType_64();
void SetType_Folder();
void FileOpenError(const QString errmsg);
Ui::MemoryCardConvertDialog m_ui;
bool isSetup = false;
@ -57,7 +57,7 @@ private:
static constexpr u32 FLAGS = FILESYSTEM_FIND_RECURSIVE | FILESYSTEM_FIND_FOLDERS | FILESYSTEM_FIND_FILES;
};
// Card capacities computed from freshly formatted superblocks.
// Card capacities computed from freshly formatted superblocks.
namespace CardCapacity
{
static constexpr size_t _8_MB = 0x1f40 * 512 * 2; //(0x1fc7 - 0x29) * 2 * 512;

View File

@ -75,7 +75,7 @@ bool MemoryCardConvertWorker::ConvertToFile(const std::string& srcFolderName, co
{
sourceFolderMemoryCard.Read(sourceBuffer.data() + address, address, FolderMemoryCard::PageSizeRaw);
address += FolderMemoryCard::PageSizeRaw;
// Only report progress every 16 pages. Substantially speeds up the conversion.
if (address % (FolderMemoryCard::PageSizeRaw * 16) == 0)
this->SetProgressValue(address);
@ -140,7 +140,7 @@ bool MemoryCardConvertWorker::ConvertToFolder(const std::string& srcFileName, co
{
targetFolderMemoryCard.Save(sourceBuffer.data() + address, address, FolderMemoryCard::PageSizeRaw);
address += FolderMemoryCard::PageSizeRaw;
// Only report progress every 16 pages. Substantially speeds up the conversion.
if (address % (FolderMemoryCard::PageSizeRaw * 16) == 0)
this->SetProgressValue(address + (i * sourceBuffer.size()));

View File

@ -101,7 +101,7 @@ void MemoryCardCreateDialog::createCard()
const QString name = m_ui.name->text();
const std::string name_str = QStringLiteral("%1.%2").arg(name)
.arg((m_fileType == MemoryCardFileType::PS1) ? QStringLiteral("mcr") : QStringLiteral("ps2"))
.toStdString();
.toStdString();
if (!Path::IsValidFileName(name_str, false))
{
QMessageBox::critical(this, tr("Create Memory Card"),
@ -123,7 +123,7 @@ void MemoryCardCreateDialog::createCard()
return;
}
#ifdef _WIN32
#ifdef _WIN32
if (m_type == MemoryCardType::File)
{
const std::string fullPath = Path::Combine(EmuFolders::MemoryCards, name_str);

View File

@ -701,13 +701,13 @@ uint32_t Achievements::ClientReadMemory(uint32_t address, uint8_t* buffer, uint3
void Achievements::ClientServerCall(
const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client)
{
HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, const std::string& content_type,
HTTPDownloader::Request::Data data) {
HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, const std::string& content_type, HTTPDownloader::Request::Data data)
{
rc_api_server_response_t rr;
rr.http_status_code = (status_code <= 0) ? (status_code == HTTPDownloader::HTTP_STATUS_CANCELLED ?
RC_API_SERVER_RESPONSE_CLIENT_ERROR :
RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) :
status_code;
RC_API_SERVER_RESPONSE_CLIENT_ERROR :
RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR)
: status_code;
rr.body_length = data.size();
rr.body = reinterpret_cast<const char*>(data.data());
@ -1486,7 +1486,7 @@ bool Achievements::ResetHardcoreMode(bool is_booting)
// because the gameid can be cached, and identify immediately on GameChanged(),
// which gets called before ResetHardcoreMode().
const bool wanted_hardcore_mode = (IsLoggedInOrLoggingIn() || s_load_game_request) &&
EmuConfig.Achievements.HardcoreMode;
EmuConfig.Achievements.HardcoreMode;
if (s_hardcore_mode == wanted_hardcore_mode)
return false;

View File

@ -12,13 +12,15 @@ using namespace R5900::Interpreter;
//#define CP2COND (vif1Regs.stat.VEW)
//Run the FINISH either side of the VCALL's as we have no control over it past here.
void VCALLMS() {
void VCALLMS()
{
_vu0FinishMicro();
vu0ExecMicro(((cpuRegs.code >> 6) & 0x7FFF));
//vif0Regs.stat.VEW = false;
}
void VCALLMSR() {
void VCALLMSR()
{
_vu0FinishMicro();
vu0ExecMicro(VU0.VI[REG_CMSAR0].US[0]);
//vif0Regs.stat.VEW = false;
@ -50,7 +52,7 @@ void BC2FL()
}
else
{
cpuRegs.pc+= 4;
cpuRegs.pc += 4;
}
}
void BC2TL()
@ -62,6 +64,6 @@ void BC2TL()
}
else
{
cpuRegs.pc+= 4;
cpuRegs.pc += 4;
}
}

View File

@ -23,7 +23,7 @@ namespace
// When this happens, the cache still fills with the data and when it gets evicted the data is lost.
// We don't emulate memory access on a logic level, so we need to ensure that we don't try to load/store to a non-existant physical address.
// This fixes the Find My Own Way demo.
// The lower parts of a cache tags structure is as follows:
// 31 - 12: The physical address cache tag.
// 11: Used by PCSX2 to indicate if the physical address is valid.
@ -468,7 +468,7 @@ namespace R5900
const int way = addr & 0x1;
CacheLine line = cache.lineAt(index, way);
line.tag.setAddr(cpuRegs.CP0.n.TagLo);
line.tag.setAddr(cpuRegs.CP0.n.TagLo);
line.tag.rawValue &= ~CacheTag::ALL_FLAGS;
line.tag.rawValue |= (cpuRegs.CP0.n.TagLo & CacheTag::ALL_FLAGS);

View File

@ -234,7 +234,7 @@ static void vSyncInfoCalc(vSyncTimingInfo* info, double framesPerSecond, u32 sca
{
hBlank /= 2;
hRender /= 2;
}
}
//TODO: Carry fixed-point math all the way through the entire vsync and hsync counting processes, and continually apply rounding
//as needed for each scheduled v/hsync related event. Much better to handle than this messed state.
@ -412,8 +412,8 @@ void UpdateVSyncRate(bool force)
s32 vdiff = vsyncCounter.deltaCycles;
hsyncCounter.deltaCycles = (hsyncCounter.Mode == MODE_HBLANK) ? vSyncInfo.hBlank : vSyncInfo.hRender;
vsyncCounter.deltaCycles = (vsyncCounter.Mode == MODE_GSBLANK) ?
vSyncInfo.GSBlank :
((vsyncCounter.Mode == MODE_VBLANK) ? vSyncInfo.Blank : vSyncInfo.Render);
vSyncInfo.GSBlank :
((vsyncCounter.Mode == MODE_VBLANK) ? vSyncInfo.Blank : vSyncInfo.Render);
hsyncCounter.startCycle += hdiff - hsyncCounter.deltaCycles;
vsyncCounter.startCycle += vdiff - vsyncCounter.deltaCycles;
@ -653,10 +653,10 @@ __fi void rcntUpdate_hScanline()
}
else
{ //HBLANK START / HRENDER End
// set up the hblank's start and end cycle information:
hsyncCounter.startCycle += vSyncInfo.hRender; // start (absolute cycle value)
hsyncCounter.deltaCycles = vSyncInfo.hBlank; // endpoint (delta from start value)
hsyncCounter.deltaCycles = vSyncInfo.hBlank; // endpoint (delta from start value)
if (!GSSMODE1reg.SINT)
{
if (!CSRreg.HSINT)
@ -765,7 +765,7 @@ __fi void rcntUpdate()
rcntSyncCounter(i);
if (counters[i].mode.ClockSource == 0x3 || !rcntCanCount(i)) // don't count hblank sources
continue;
continue;
_cpuTestOverflow(i);
_cpuTestTarget(i);
@ -813,7 +813,7 @@ static __fi void rcntStartGate(bool isVblank, u32 sCycle)
switch (counters[i].mode.GateMode)
{
case 0x0: //Count When Signal is low (V_RENDER ONLY)
case 0x0: // Count When Signal is low (V_RENDER ONLY)
// Just set the start cycle -- counting will be done as needed
// for events (overflows, targets, mode changes, and the gate off below)
@ -955,7 +955,7 @@ __fi u32 rcntRcount(int index)
u32 ret;
rcntSyncCounter(index);
ret = counters[index].count;
// Spams the Console.

View File

@ -355,10 +355,10 @@ bool GSopen(const Pcsx2Config::GSOptions& config, GSRendererType renderer, u8* b
if (!res)
{
Host::ReportErrorAsync(
"Error", fmt::format(TRANSLATE_FS("GS","Failed to create render device. This may be due to your GPU not supporting the "
"chosen renderer ({}), or because your graphics drivers need to be updated."),
Pcsx2Config::GSOptions::GetRendererName(GSConfig.Renderer)));
Host::ReportErrorAsync("Error",
fmt::format(TRANSLATE_FS("GS", "Failed to create render device. This may be due to your GPU not supporting the "
"chosen renderer ({}), or because your graphics drivers need to be updated."),
Pcsx2Config::GSOptions::GetRendererName(GSConfig.Renderer)));
return false;
}
@ -500,7 +500,7 @@ void GSEndCapture()
{
if (g_gs_renderer)
g_gs_renderer->EndCapture();
}
}
void GSPresentCurrentFrame()
{
@ -661,7 +661,7 @@ void GSgetStats(SmallStringBase& info)
const double fillrate = pm.Get(GSPerfMon::Fillrate);
double pps = fps * fillrate;
char prefix = '\0';
if (pps >= 170000000)
{
pps /= 1073741824; // Gpps
@ -689,7 +689,7 @@ void GSgetStats(SmallStringBase& info)
(int)pm.Get(GSPerfMon::Draw),
pm.Get(GSPerfMon::Swizzle) / 1024,
pm.Get(GSPerfMon::Unswizzle) / 1024,
pps,prefix);
pps, prefix);
}
else if (GSCurrentRenderer == GSRendererType::Null)
{

View File

@ -1384,12 +1384,12 @@ TinyString GSCapture::GetElapsedTime()
if (s_video_stream)
{
seconds = (s_next_video_pts * static_cast<s64>(s_video_codec_context->time_base.num)) /
static_cast<s64>(s_video_codec_context->time_base.den);
static_cast<s64>(s_video_codec_context->time_base.den);
}
else if (s_audio_stream)
{
seconds = (s_next_audio_pts * static_cast<s64>(s_audio_codec_context->time_base.num)) /
static_cast<s64>(s_audio_codec_context->time_base.den);
static_cast<s64>(s_audio_codec_context->time_base.den);
}
else
{

View File

@ -38,7 +38,7 @@ namespace GSCapture
CodecList GetVideoCodecList(const char* container);
CodecList GetAudioCodecList(const char* container);
using FormatName = std::pair<int , std::string>; // id,name
using FormatName = std::pair<int, std::string>; // id,name
using FormatList = std::vector<FormatName>;
FormatList GetVideoFormatList(const char* codec);
}; // namespace GSCapture

View File

@ -185,7 +185,7 @@ bool GSClut::CanLoadCLUT(const GIFRegTEX0& TEX0, const bool update_CBP)
case 4:
if (m_CBP[0] == TEX0.CBP)
return false;
if(update_CBP)
if (update_CBP)
m_CBP[0] = TEX0.CBP;
break;
case 5:
@ -531,7 +531,7 @@ void GSClut::GetAlphaMinMax32(int& amin_out, int& amax_out)
void GSClut::WriteCLUT_T32_I8_CSM1(const u32* RESTRICT src, u16* RESTRICT clut, u16 offset)
{
// This is required when CSA is offset from the base of the CLUT so we point to the right data
for (int i = offset; i < 16; i ++)
for (int i = offset; i < 16; i++)
{
const int off = i << 4; // WriteCLUT_T32_I4_CSM1 loads 16 at a time
// Source column

View File

@ -509,15 +509,15 @@ GSVector4i GSLocalMemory::GetRectForPageOffset(u32 base_bp, u32 offset_bp, u32 b
return GSVector4i(pgs * page_offset_xy).xyxy() + GSVector4i::loadh(pgs);
}
bool GSLocalMemory::HasOverlap(const u32 src_bp, const u32 src_bw, const u32 src_psm, const GSVector4i src_rect
, const u32 dst_bp, const u32 dst_bw, const u32 dst_psm, const GSVector4i dst_rect)
bool GSLocalMemory::HasOverlap(const u32 src_bp, const u32 src_bw, const u32 src_psm, const GSVector4i src_rect,
const u32 dst_bp, const u32 dst_bw, const u32 dst_psm, const GSVector4i dst_rect)
{
const u32 src_start_bp = GSLocalMemory::GetStartBlockAddress(src_bp, src_bw, src_psm, src_rect) & ~(GS_BLOCKS_PER_PAGE - 1);
const u32 dst_start_bp = GSLocalMemory::GetStartBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) & ~(GS_BLOCKS_PER_PAGE - 1);
u32 src_end_bp = ((GSLocalMemory::GetEndBlockAddress(src_bp, src_bw, src_psm, src_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
u32 dst_end_bp = ((GSLocalMemory::GetEndBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
if (src_start_bp == src_end_bp)
{
src_end_bp = (src_end_bp + GS_BLOCKS_PER_PAGE) & ~(GS_MAX_BLOCKS - 1);

View File

@ -23,7 +23,7 @@ void GSPerfMon::EndFrame(bool frame_only)
{
m_frame++;
if(!frame_only)
if (!frame_only)
m_count++;
}

View File

@ -586,8 +586,8 @@ void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
{
// Check all three formats, since the feature means any can be used.
m_features.dxt_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC1_UNORM) &&
SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC2_UNORM) &&
SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC3_UNORM);
SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC2_UNORM) &&
SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC3_UNORM);
m_features.bptc_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC7_UNORM);
@ -595,8 +595,8 @@ void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
m_features.cas_sharpening = (m_feature_level >= D3D_FEATURE_LEVEL_11_0);
m_max_texture_size = (m_feature_level >= D3D_FEATURE_LEVEL_11_0) ?
D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION :
D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION :
D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
}
bool GSDevice11::HasSurface() const
@ -752,7 +752,7 @@ bool GSDevice11::CreateSwapChain()
else
{
Console.ErrorFmt("D3D11: GetParent() on swap chain to get factory failed: {}", Error::CreateHResult(hr).GetDescription());
}
}
if (!CreateSwapChainRTV())
{
@ -801,7 +801,7 @@ bool GSDevice11::CreateSwapChainRTV()
SUCCEEDED(m_swap_chain->GetDesc(&desc)))
{
m_window_info.surface_refresh_rate = static_cast<float>(desc.BufferDesc.RefreshRate.Numerator) /
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
}
}
@ -1263,7 +1263,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, bool red, bool green, bool blue, bool alpha, ShaderConvert shader)
{
const u8 index = static_cast<u8>(red) | (static_cast<u8>(green) << 1) | (static_cast<u8>(blue) << 2) |
(static_cast<u8>(alpha) << 3);
(static_cast<u8>(alpha) << 3);
StretchRect(sTex, sRect, dTex, dRect, m_convert.ps[static_cast<int>(shader)].get(), nullptr,
m_convert.bs[index].get(), false);
}
@ -1316,7 +1316,7 @@ void GSDevice11::StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture*
};
IASetVertexBuffer(vertices, sizeof(vertices[0]), std::size(vertices));
IASetVertexBuffer(vertices, sizeof(vertices[0]), std::size(vertices));
IASetInputLayout(m_convert.il.get());
IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
@ -1795,8 +1795,8 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
}};
const u8 index = (static_cast<u8>(ssel.IsMipFilterLinear()) << 2) |
(static_cast<u8>(ssel.IsMagFilterLinear()) << 1) |
static_cast<u8>(ssel.IsMinFilterLinear());
(static_cast<u8>(ssel.IsMagFilterLinear()) << 1) |
static_cast<u8>(ssel.IsMinFilterLinear());
sd.Filter = filters[index];
}

View File

@ -63,7 +63,7 @@ bool GSTexture11::Update(const GSVector4i& r, const void* data, int pitch, int l
g_perfmon.Put(GSPerfMon::TextureUploads, 1);
const u32 bs = GetCompressedBlockSize();
const D3D11_BOX box = {Common::AlignDownPow2((u32)r.left, bs), Common::AlignDownPow2((u32)r.top, bs), 0U,
Common::AlignUpPow2((u32)r.right, bs), Common::AlignUpPow2((u32)r.bottom, bs), 1U};
const UINT subresource = layer; // MipSlice + (ArraySlice * MipLevels).

View File

@ -134,7 +134,7 @@ bool GSDevice12::SupportsTextureFormat(DXGI_FORMAT format)
D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format};
return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support, sizeof(support))) &&
(support.Support1 & required) == required;
(support.Support1 & required) == required;
}
u32 GSDevice12::GetAdapterVendorID() const
@ -958,7 +958,7 @@ bool GSDevice12::CreateSwapChainRTV()
SUCCEEDED(m_swap_chain->GetDesc(&desc)))
{
m_window_info.surface_refresh_rate = static_cast<float>(desc.BufferDesc.RefreshRate.Numerator) /
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
static_cast<float>(desc.BufferDesc.RefreshRate.Denominator);
}
}
@ -1238,8 +1238,8 @@ bool GSDevice12::CheckFeatures(const u32& vendor_id)
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
m_features.dxt_textures = SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&
SupportsTextureFormat(DXGI_FORMAT_BC3_UNORM);
m_features.bptc_textures = SupportsTextureFormat(DXGI_FORMAT_BC7_UNORM);
m_max_texture_size = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION;
@ -1643,8 +1643,8 @@ void GSDevice12::BeginRenderPassForStretchRect(
GSTexture12* dTex, const GSVector4i& dtex_rc, const GSVector4i& dst_rc, bool allow_discard)
{
const D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE load_op = (allow_discard && dst_rc.eq(dtex_rc)) ?
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD :
GetLoadOpForTexture(dTex);
D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_DISCARD :
GetLoadOpForTexture(dTex);
dTex->SetState(GSTexture::State::Dirty);
if (dTex->GetType() != GSTexture::Type::DepthStencil)
@ -1742,8 +1742,8 @@ void GSDevice12::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
(sTex[0] && (sTex[0]->GetState() == GSTexture::State::Dirty ||
(sTex[0]->GetState() == GSTexture::State::Cleared || sTex[0]->GetClearColor() != 0)));
const bool has_input_1 = (PMODE.SLBG == 0 || feedback_write_2_but_blend_bg) && sTex[1] &&
(sTex[1]->GetState() == GSTexture::State::Dirty ||
(sTex[1]->GetState() == GSTexture::State::Cleared || sTex[1]->GetClearColor() != 0));
(sTex[1]->GetState() == GSTexture::State::Dirty ||
(sTex[1]->GetState() == GSTexture::State::Cleared || sTex[1]->GetClearColor() != 0));
if (has_input_0)
{
static_cast<GSTexture12*>(sTex[0])->CommitClear();
@ -2261,7 +2261,7 @@ bool GSDevice12::GetSampler(D3D12DescriptorHandle* cpu_handle, GSHWDrawConfig::S
}};
const u8 index = (static_cast<u8>(ss.IsMipFilterLinear()) << 2) |
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) | static_cast<u8>(ss.IsMinFilterLinear());
(static_cast<u8>(ss.IsMagFilterLinear()) << 1) | static_cast<u8>(ss.IsMinFilterLinear());
sd.Filter = filters[index];
}
@ -2448,8 +2448,7 @@ bool GSDevice12::CompileConvertPipelines()
gpb.SetNoBlendingState();
gpb.SetVertexShader(m_convert_vs.get());
for (ShaderConvert i = ShaderConvert::COPY; static_cast<int>(i) < static_cast<int>(ShaderConvert::Count);
i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
for (ShaderConvert i = ShaderConvert::COPY; i < ShaderConvert::Count; i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
{
const bool depth = HasDepthOutput(i);
const int index = static_cast<int>(i);
@ -2621,8 +2620,7 @@ bool GSDevice12::CompilePresentPipelines()
gpb.SetNoStencilState();
gpb.SetRenderTarget(0, DXGI_FORMAT_R8G8B8A8_UNORM);
for (PresentShader i = PresentShader::COPY; static_cast<int>(i) < static_cast<int>(PresentShader::Count);
i = static_cast<PresentShader>(static_cast<int>(i) + 1))
for (PresentShader i = PresentShader::COPY; i < PresentShader::Count; i = static_cast<PresentShader>(static_cast<int>(i) + 1))
{
const int index = static_cast<int>(i);
@ -2963,8 +2961,8 @@ GSDevice12::ComPtr<ID3D12PipelineState> GSDevice12::CreateTFXPipeline(const Pipe
if (p.rt)
{
const GSTexture::Format format = IsDATEModePrimIDInit(p.ps.date) ?
GSTexture::Format::PrimID :
(p.ps.colclip_hw ? GSTexture::Format::ColorClip : GSTexture::Format::Color);
GSTexture::Format::PrimID :
(p.ps.colclip_hw ? GSTexture::Format::ColorClip : GSTexture::Format::Color);
DXGI_FORMAT native_format;
LookupNativeFormat(format, nullptr, nullptr, &native_format, nullptr);
@ -3650,8 +3648,8 @@ bool GSDevice12::ApplyTFXState(bool already_execed)
{
m_current_root_signature = RootSignature::TFX;
flags |= DIRTY_FLAG_VS_CONSTANT_BUFFER_BINDING | DIRTY_FLAG_PS_CONSTANT_BUFFER_BINDING |
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE |
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_PIPELINE;
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE | DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE |
DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 | DIRTY_FLAG_PIPELINE;
cmdlist->SetGraphicsRootSignature(m_tfx_root_signature.get());
}

View File

@ -544,11 +544,11 @@ private:
DIRTY_FLAG_STENCIL_REF = (1 << 19),
DIRTY_BASE_STATE = DIRTY_FLAG_VS_CONSTANT_BUFFER_BINDING | DIRTY_FLAG_PS_CONSTANT_BUFFER_BINDING |
DIRTY_FLAG_VS_VERTEX_BUFFER_BINDING | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE |
DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 |
DIRTY_FLAG_VERTEX_BUFFER | DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_PRIMITIVE_TOPOLOGY |
DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET | DIRTY_FLAG_PIPELINE |
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_STENCIL_REF,
DIRTY_FLAG_VS_VERTEX_BUFFER_BINDING | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE |
DIRTY_FLAG_SAMPLERS_DESCRIPTOR_TABLE | DIRTY_FLAG_TEXTURES_DESCRIPTOR_TABLE_2 |
DIRTY_FLAG_VERTEX_BUFFER | DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_PRIMITIVE_TOPOLOGY |
DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR | DIRTY_FLAG_RENDER_TARGET | DIRTY_FLAG_PIPELINE |
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_STENCIL_REF,
DIRTY_TFX_STATE =
DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES | DIRTY_FLAG_TFX_SAMPLERS | DIRTY_FLAG_TFX_RT_TEXTURES,

View File

@ -125,7 +125,7 @@ std::unique_ptr<GSTexture12> GSTexture12::Create(Type type, Format format, int w
// This is a little annoying. basically, to do mipmap generation, we need to be a render target.
// If it's a compressed texture, we won't be generating mips anyway, so this should be fine.
desc.Flags = (levels > 1 && !IsCompressedFormat(format)) ? D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET :
D3D12_RESOURCE_FLAG_NONE;
D3D12_RESOURCE_FLAG_NONE;
state = D3D12_RESOURCE_STATE_COPY_DEST;
}
break;

View File

@ -1093,7 +1093,7 @@ bool GSHwHack::OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds,
rt_again->m_texture = tex;
rt = tex;
}
GSVector2i rt_size(rt->GetSize());
// This is awful, but so is the CRC hack... it's a texture shuffle split horizontally instead of vertically.
@ -1102,14 +1102,14 @@ bool GSHwHack::OI_SonicUnleashed(GSRendererHW& r, GSTexture* rt, GSTexture* ds,
if (rt_again->m_unscaled_size.x < src->m_unscaled_size.x || rt_again->m_unscaled_size.y < src->m_unscaled_size.y)
{
GSVector2i new_size = GSVector2i(std::max(rt_again->m_unscaled_size.x, src->m_unscaled_size.x),
std::max(rt_again->m_unscaled_size.y, src->m_unscaled_size.y));
std::max(rt_again->m_unscaled_size.y, src->m_unscaled_size.y));
rt_again->ResizeTexture(new_size.x, new_size.y);
rt = rt_again->m_texture;
rt_size = new_size * GSVector2i(src->GetScale());
rt_again->UpdateDrawn(GSVector4i::loadh(new_size));
}
}
const GSVector2i copy_size(std::min(rt_size.x, src_size.x), std::min(rt_size.y, src_size.y));

View File

@ -332,7 +332,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
const GSVertex second_vert = (start_verts[0].XYZ.X <= start_verts[1].XYZ.X) ? start_verts[1] : start_verts[0];
// vertex position is 8 to 16 pixels, therefore it is the 16-31 bits of the colors
const int pos = (first_vert.XYZ.X - o.OFX) & 0xFF;
// Read texture is 8 to 16 pixels (same as above)
const float tw = static_cast<float>(1u << m_cached_ctx.TEX0.TW);
int tex_pos = (PRIM->FST) ? first_vert.U : static_cast<int>(tw * first_vert.ST.S * 16.0f);
@ -359,7 +359,7 @@ void GSRendererHW::ConvertSpriteTextureShuffle(u32& process_rg, u32& process_ba,
const u32 minu = (m_cached_ctx.CLAMP.MINU & 8);
if (maxu)
{
process_ba |= SHUFFLE_READ;
process_ba |= SHUFFLE_READ;
process_rg &= ~SHUFFLE_READ;
if (!PRIM->ABE && (process_rg & SHUFFLE_WRITE))
{
@ -1124,7 +1124,7 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex, const b
height = std::min(height, valid_max_size);
}
return GSVector2i(width, height);
return GSVector2i(width, height);
}
GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex, const bool can_expand, const bool is_shuffle)
@ -1167,7 +1167,7 @@ bool GSRendererHW::IsPossibleChannelShuffle() const
const int draw_height = std::abs(v[1].XYZ.Y - v[0].XYZ.Y) >> 4;
const bool mask_clamp = (m_cached_ctx.CLAMP.WMS | m_cached_ctx.CLAMP.WMT) & 0x2;
const bool draw_match = (draw_height == 2) || (draw_width == 8);
if (draw_match || mask_clamp)
@ -1616,18 +1616,18 @@ bool GSRendererHW::IsRTWritten()
const u32 written_bits = (~m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk);
const GIFRegALPHA ALPHA = m_context->ALPHA;
return (
// A not masked
(written_bits & 0xFF000000u) != 0) ||
(
// RGB not entirely masked
((written_bits & 0x00FFFFFFu) != 0) &&
// RGB written through no-blending, or blend result being non-zero
(!PRIM->ABE || // not blending
ALPHA.D != 1 || // additive to Cs
(ALPHA.A != ALPHA.B && // left side is not zero
(ALPHA.C == 1 || // multiply by Ad
(ALPHA.C == 2 && ALPHA.FIX != 0) || // multiply by 0
(ALPHA.C == 0 && GetAlphaMinMax().max != 0)))));
// A not masked
(written_bits & 0xFF000000u) != 0) ||
(
// RGB not entirely masked
((written_bits & 0x00FFFFFFu) != 0) &&
// RGB written through no-blending, or blend result being non-zero
(!PRIM->ABE || // not blending
ALPHA.D != 1 || // additive to Cs
(ALPHA.A != ALPHA.B && // left side is not zero
(ALPHA.C == 1 || // multiply by Ad
(ALPHA.C == 2 && ALPHA.FIX != 0) || // multiply by 0
(ALPHA.C == 0 && GetAlphaMinMax().max != 0)))));
}
bool GSRendererHW::IsDepthAlwaysPassing()
@ -1636,8 +1636,8 @@ bool GSRendererHW::IsDepthAlwaysPassing()
const int check_index = m_vt.m_primclass == GS_SPRITE_CLASS ? 1 : 0;
// Depth is always pass/fail (no read) and write are discarded.
return (!m_cached_ctx.TEST.ZTE || m_cached_ctx.TEST.ZTST <= ZTST_ALWAYS) ||
// Depth test will always pass
(m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[check_index].XYZ.Z, max_z) == max_z);
// Depth test will always pass
(m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[check_index].XYZ.Z, max_z) == max_z);
}
bool GSRendererHW::IsUsingCsInBlend()
@ -1673,14 +1673,14 @@ bool GSRendererHW::IsTBPFrameOrZ(u32 tbp, bool frame_only)
const u32 max_z = (0xFFFFFFFF >> (GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].fmt * 8));
const bool no_rt = (!IsRTWritten() && !m_cached_ctx.TEST.DATE);
const bool no_ds = (
// Depth is always pass/fail (no read) and write are discarded.
(zm != 0 && m_cached_ctx.TEST.ZTST <= ZTST_ALWAYS) ||
// Depth test will always pass
(zm != 0 && m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[0].XYZ.Z, max_z) == max_z) ||
// Depth will be written through the RT
(!no_rt && m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP && !PRIM->TME && zm == 0 && (fm & fm_mask) == 0 && m_cached_ctx.TEST.ZTE)) ||
// No color or Z being written.
(no_rt && zm != 0);
// Depth is always pass/fail (no read) and write are discarded.
(zm != 0 && m_cached_ctx.TEST.ZTST <= ZTST_ALWAYS) ||
// Depth test will always pass
(zm != 0 && m_cached_ctx.TEST.ZTST == ZTST_GEQUAL && m_vt.m_eq.z && std::min(m_vertex.buff[0].XYZ.Z, max_z) == max_z) ||
// Depth will be written through the RT
(!no_rt && m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP && !PRIM->TME && zm == 0 && (fm & fm_mask) == 0 && m_cached_ctx.TEST.ZTE)) ||
// No color or Z being written.
(no_rt && zm != 0);
// Relying a lot on the optimizer here... I don't like it.
return (is_frame && !no_rt) || (is_z && !no_ds && !frame_only);
@ -1777,7 +1777,7 @@ void GSRendererHW::InvalidateLocalMem(const GIFRegBITBLTBUF& BITBLTBUF, const GS
if (!(iter->draw == s_n && BITBLTBUF.SBP == iter->blit.DBP && iter->blit.DPSM == BITBLTBUF.SPSM && r.eq(iter->rect)))
continue;
g_texture_cache->InvalidateVideoMem(m_mem.GetOffset(BITBLTBUF.SBP, BITBLTBUF.SBW, BITBLTBUF.SPSM), r);
skip = true;
break;
@ -1917,12 +1917,12 @@ void GSRendererHW::SwSpriteRender()
const GSVertex& v = m_index.tail > 0 ? m_vertex.buff[m_index.buff[m_index.tail - 1]] : GSVertex(); // Last vertex if any.
const GSVector4i vc = GSVector4i(v.RGBAQ.R, v.RGBAQ.G, v.RGBAQ.B, v.RGBAQ.A) // 0x000000AA000000BB000000GG000000RR
.ps32(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
.ps32(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
const GSVector4i a_mask = GSVector4i::xff000000().u8to16(); // 0x00FF00000000000000FF000000000000
const GSVector4i a_mask = GSVector4i::xff000000().u8to16(); // 0x00FF00000000000000FF000000000000
const bool fb_mask_enabled = m_cached_ctx.FRAME.FBMSK != 0x0;
const GSVector4i fb_mask = GSVector4i(m_cached_ctx.FRAME.FBMSK).u8to16(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
const GSVector4i fb_mask = GSVector4i(m_cached_ctx.FRAME.FBMSK).u8to16(); // 0x00AA00BB00GG00RR00AA00BB00GG00RR
const u8 tex0_tfx = m_cached_ctx.TEX0.TFX;
const u8 tex0_tcc = m_cached_ctx.TEX0.TCC;
@ -2250,8 +2250,8 @@ void GSRendererHW::Draw()
// Tomb Raider: Underworld does similar, except with R, G, B in separate palettes, therefore
// we need to split on those too.
m_channel_shuffle = !m_channel_shuffle_abort && IsPossibleChannelShuffle() && m_last_channel_shuffle_fbmsk == m_context->FRAME.FBMSK &&
m_last_channel_shuffle_fbp <= m_context->FRAME.Block() && m_last_channel_shuffle_end_block > m_context->FRAME.Block() &&
m_last_channel_shuffle_tbp <= m_context->TEX0.TBP0;
m_last_channel_shuffle_fbp <= m_context->FRAME.Block() && m_last_channel_shuffle_end_block > m_context->FRAME.Block() &&
m_last_channel_shuffle_tbp <= m_context->TEX0.TBP0;
if (m_channel_shuffle)
{
@ -2296,7 +2296,7 @@ void GSRendererHW::Draw()
else
m_conf.scissor.z = std::min(m_conf.scissor.z, static_cast<int>((m_channel_shuffle_width * 64) * m_conf.cb_ps.ScaleFactor.z));
}
m_last_rt->UpdateValidity(valid_area);
g_gs_device->RenderHW(m_conf);
@ -2308,7 +2308,7 @@ void GSRendererHW::Draw()
if (m_last_rt && GSConfig.SaveRT)
{
const u64 frame = g_perfmon.GetFrame();
std::string s = GetDrawDumpPath("%05d_f%05lld_rt1_%05x_(%05x)_%s.bmp", s_n - 1, frame, m_last_channel_shuffle_fbp, m_last_rt->m_TEX0.TBP0, GSUtil::GetPSMName(m_cached_ctx.FRAME.PSM));
m_last_rt->m_texture->Save(s);
@ -2354,9 +2354,9 @@ void GSRendererHW::Draw()
// Note: do it first so we know if frame/depth writes are masked
u32 fm = m_cached_ctx.FRAME.FBMSK;
u32 zm = (m_cached_ctx.ZBUF.ZMSK || m_cached_ctx.TEST.ZTE == 0 ||
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ZTST_NEVER && m_cached_ctx.TEST.AFAIL != AFAIL_ZB_ONLY)) ?
0xffffffffu :
0;
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ZTST_NEVER && m_cached_ctx.TEST.AFAIL != AFAIL_ZB_ONLY)) ?
0xffffffffu :
0;
const u32 fm_mask = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk;
// Note required to compute TryAlphaTest below. So do it now.
@ -2424,8 +2424,8 @@ void GSRendererHW::Draw()
bool no_rt = (!IsRTWritten() && !m_cached_ctx.TEST.DATE);
const bool all_depth_tests_pass = IsDepthAlwaysPassing();
bool no_ds = (zm != 0 && all_depth_tests_pass) ||
// No color or Z being written.
(no_rt && zm != 0);
// No color or Z being written.
(no_rt && zm != 0);
// No Z test if no z buffer.
if (no_ds || all_depth_tests_pass)
@ -2465,7 +2465,6 @@ void GSRendererHW::Draw()
g_gs_device->Recycle(colclip_texture);
g_gs_device->SetColorClipTexture(nullptr);
}
else
DevCon.Warning("HW: Error resolving colclip texture for pre-draw resolve");
@ -2922,13 +2921,13 @@ void GSRendererHW::Draw()
(m_vt.m_primclass == GS_SPRITE_CLASS || (m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_index.tail % 6) == 0 && TrianglesAreQuads(true) && m_index.tail > 6)))
{
// Tail check is to make sure we have enough strips to go all the way across the page, or if it's using a region clamp could be used to draw strips.
if (GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 &&
if (GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 &&
(m_index.tail >= (m_cached_ctx.TEX0.TBW * 2) || m_cached_ctx.TEX0.TBP0 == m_cached_ctx.FRAME.Block() || m_cached_ctx.CLAMP.WMS > CLAMP_CLAMP || m_cached_ctx.CLAMP.WMT > CLAMP_CLAMP))
{
const GSVertex* v = &m_vertex.buff[0];
const int first_x = std::clamp((static_cast<int>(((v[0].XYZ.X - m_context->XYOFFSET.OFX) + 8))) >> 4, 0, 2048);
const bool offset_last = PRIM->FST ? (v[1].U > v[0].U) : ((v[1].ST.S / v[1].RGBAQ.Q) > (v[0].ST.S / v[1].RGBAQ.Q));
const bool offset_last = PRIM->FST ? (v[1].U > v[0].U) : ((v[1].ST.S / v[1].RGBAQ.Q) > (v[0].ST.S / v[1].RGBAQ.Q));
const int first_u = PRIM->FST ? ((v[0].U + (offset_last ? 0 : 9)) >> 4) : std::clamp(static_cast<int>(((1 << m_cached_ctx.TEX0.TW) * (v[0].ST.S / v[1].RGBAQ.Q)) + (offset_last ? 0.0f : 0.6f)), 0, 2048);
const int second_u = PRIM->FST ? ((v[1].U + (offset_last ? 9 : 0)) >> 4) : std::clamp(static_cast<int>(((1 << m_cached_ctx.TEX0.TW) * (v[1].ST.S / v[1].RGBAQ.Q)) + (offset_last ? 0.6f : 0.0f)), 0, 2048);
// offset coordinates swap around RG/BA. (Ace Combat)
@ -3007,9 +3006,9 @@ void GSRendererHW::Draw()
}
else
{
src = tex_psm.depth ? g_texture_cache->LookupDepthSource(true, TEX0, m_cached_ctx.TEXA, MIP_CLAMP, tmm.coverage, possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha) :
g_texture_cache->LookupSource(true, TEX0, m_cached_ctx.TEXA, MIP_CLAMP, tmm.coverage, (GSConfig.HWMipmap || GSConfig.TriFilter == TriFiltering::Forced) ? &hash_lod_range : nullptr,
possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha);
src = tex_psm.depth ? g_texture_cache->LookupDepthSource(true, TEX0, m_cached_ctx.TEXA, MIP_CLAMP, tmm.coverage, possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha)
: g_texture_cache->LookupSource(true, TEX0, m_cached_ctx.TEXA, MIP_CLAMP, tmm.coverage, (GSConfig.HWMipmap || GSConfig.TriFilter == TriFiltering::Forced) ? &hash_lod_range : nullptr,
possible_shuffle, m_vt.IsLinear(), m_cached_ctx.FRAME, req_color, req_alpha);
if (!src) [[unlikely]]
{
@ -3022,9 +3021,8 @@ void GSRendererHW::Draw()
const u32 draw_end = GSLocalMemory::GetEndBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r) + 1;
const u32 draw_start = GSLocalMemory::GetStartBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r);
draw_uses_target = src->m_from_target && ((src->m_from_target_TEX0.TBP0 <= draw_start &&
src->m_from_target->UnwrappedEndBlock() > m_cached_ctx.FRAME.Block()) ||
(m_cached_ctx.FRAME.Block() < src->m_from_target_TEX0.TBP0 && draw_end > src->m_from_target_TEX0.TBP0));
draw_uses_target = src->m_from_target && ((src->m_from_target_TEX0.TBP0 <= draw_start && src->m_from_target->UnwrappedEndBlock() > m_cached_ctx.FRAME.Block()) ||
(m_cached_ctx.FRAME.Block() < src->m_from_target_TEX0.TBP0 && draw_end > src->m_from_target_TEX0.TBP0));
if (possible_shuffle && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp != 16)
possible_shuffle &= draw_uses_target;
@ -3047,9 +3045,9 @@ void GSRendererHW::Draw()
u32 new_fm = m_context->FRAME.FBMSK;
u32 new_zm = (m_cached_ctx.ZBUF.ZMSK || m_cached_ctx.TEST.ZTE == 0 ||
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ZTST_NEVER && m_cached_ctx.TEST.AFAIL != AFAIL_ZB_ONLY)) ?
0xffffffffu :
0;
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ZTST_NEVER && m_cached_ctx.TEST.AFAIL != AFAIL_ZB_ONLY)) ?
0xffffffffu :
0;
if (m_cached_ctx.TEST.ATE && GSRenderer::TryAlphaTest(new_fm, new_zm))
{
m_cached_ctx.TEST.ATE = false;
@ -3059,10 +3057,10 @@ void GSRendererHW::Draw()
zm = new_zm;
no_rt = no_rt || (!IsRTWritten() && !m_cached_ctx.TEST.DATE);
no_ds = no_ds || (zm != 0 && all_depth_tests_pass) ||
// Depth will be written through the RT
(!no_rt && m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP && !PRIM->TME && zm == 0 && (fm & fm_mask) == 0 && m_cached_ctx.TEST.ZTE) ||
// No color or Z being written.
(no_rt && zm != 0);
// Depth will be written through the RT
(!no_rt && m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP && !PRIM->TME && zm == 0 && (fm & fm_mask) == 0 && m_cached_ctx.TEST.ZTE) ||
// No color or Z being written.
(no_rt && zm != 0);
if (no_rt && no_ds)
{
GL_INS("HW: Late draw cancel because no pixels pass alpha test.");
@ -3362,16 +3360,18 @@ void GSRendererHW::Draw()
if (!no_rt)
{
possible_shuffle |= draw_sprite_tex && m_process_texture && m_primitive_covers_without_gaps != NoGapsType::FullCover && (((src && src->m_target && src->m_from_target && src->m_from_target->m_32_bits_fmt) &&
(GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 || draw_uses_target) && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) ||
IsPossibleChannelShuffle());
possible_shuffle |= draw_sprite_tex && m_process_texture && m_primitive_covers_without_gaps != NoGapsType::FullCover &&
(((src && src->m_target && src->m_from_target && src->m_from_target->m_32_bits_fmt) &&
(GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].bpp == 16 || draw_uses_target) &&
GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) ||
IsPossibleChannelShuffle());
const bool possible_horizontal_texture_shuffle = possible_shuffle && src && src->m_from_target && m_r.w <= src->m_from_target->m_valid.w && m_r.z > src->m_from_target->m_valid.z && m_cached_ctx.FRAME.FBW > src->m_from_target_TEX0.TBW;
// FBW is going to be wrong for channel shuffling into a new target, so take it from the source.
FRAME_TEX0.U64 = 0;
FRAME_TEX0.TBP0 = ((m_last_channel_shuffle_end_block + 1) == m_cached_ctx.FRAME.Block() && possible_shuffle) ? m_last_channel_shuffle_fbp : m_cached_ctx.FRAME.Block();
FRAME_TEX0.TBW = (possible_horizontal_texture_shuffle || (possible_shuffle && src && src->m_from_target && IsPossibleChannelShuffle()&& m_cached_ctx.FRAME.FBW <= 2)) ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;
FRAME_TEX0.TBW = (possible_horizontal_texture_shuffle || (possible_shuffle && src && src->m_from_target && IsPossibleChannelShuffle() && m_cached_ctx.FRAME.FBW <= 2)) ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;
FRAME_TEX0.PSM = m_cached_ctx.FRAME.PSM;
// Don't clamp on shuffle, the height cache may troll us with the REAL height.
@ -3459,8 +3459,8 @@ void GSRendererHW::Draw()
return;
}
rt = g_texture_cache->CreateTarget(FRAME_TEX0, t_size, GetValidSize(src, possible_shuffle), (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && scale_draw < 0 && is_possible_mem_clear != ClearType::NormalClear) ? ((src && src->m_from_target) ? src->m_from_target->GetScale() : (ds ? ds->m_scale : 1.0f)) : target_scale,
GSTextureCache::RenderTarget, true, fm, false, force_preload, preserve_rt_color || possible_shuffle, lookup_rect, src);
rt = g_texture_cache->CreateTarget(FRAME_TEX0, t_size, GetValidSize(src, possible_shuffle), (GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && scale_draw < 0 && is_possible_mem_clear != ClearType::NormalClear) ? ((src && src->m_from_target) ? src->m_from_target->GetScale() : (ds ? ds->m_scale : 1.0f)) : target_scale,
GSTextureCache::RenderTarget, true, fm, false, force_preload, preserve_rt_color || possible_shuffle, lookup_rect, src);
if (!rt) [[unlikely]]
{
@ -3474,8 +3474,8 @@ void GSRendererHW::Draw()
rt->UpdateValidity(GSVector4i::loadh(GSVector2i(GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.x, GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].pgs.y)), true);
}
if (src && !src->m_from_target && GSLocalMemory::m_psm[src->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[m_context->FRAME.PSM].bpp &&
(GSUtil::GetChannelMask(src->m_TEX0.PSM) & GSUtil::GetChannelMask(m_context->FRAME.PSM)) != 0)
if (src && !src->m_from_target && GSLocalMemory::m_psm[src->m_TEX0.PSM].bpp == GSLocalMemory::m_psm[m_context->FRAME.PSM].bpp &&
(GSUtil::GetChannelMask(src->m_TEX0.PSM) & GSUtil::GetChannelMask(m_context->FRAME.PSM)) != 0)
{
const u32 draw_end = GSLocalMemory::GetEndBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r) + 1;
const u32 draw_start = GSLocalMemory::GetStartBlockAddress(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r);
@ -3494,7 +3494,7 @@ void GSRendererHW::Draw()
src->m_valid_rect = rt->m_valid;
src->m_alpha_minmax.first = rt->m_alpha_min;
src->m_alpha_minmax.second = rt->m_alpha_max;
const int target_width = std::max(FRAME_TEX0.TBW, 1U);
const int page_offset = (src->m_TEX0.TBP0 - rt->m_TEX0.TBP0) >> 5;
const int vertical_page_offset = page_offset / target_width;
@ -3652,7 +3652,7 @@ void GSRendererHW::Draw()
}
}
}
}
}
// Z or RT are offset from each other, so we need a temp Z to align it
if (ds && rt && ((m_cached_ctx.ZBUF.Block() - ds->m_TEX0.TBP0) != (m_cached_ctx.FRAME.Block() - rt->m_TEX0.TBP0) || (g_texture_cache->GetTemporaryZ() != nullptr && g_texture_cache->GetTemporaryZInfo().ZBP == ds->m_TEX0.TBP0)))
{
@ -3716,7 +3716,7 @@ void GSRendererHW::Draw()
const GSDrawingContext& next_ctx = m_env.CTXT[get_next_ctx];
const int vertical_page_offset = (rt_page_offset / std::max(static_cast<int>(rt->m_TEX0.TBW), 1));
const int vertical_offset = vertical_page_offset * frame_psm.pgs.y;
const int horizontal_offset = (rt_page_offset - (vertical_page_offset * std::max(static_cast<int>(rt->m_TEX0.TBW), 1))) * frame_psm.pgs.x;
const int horizontal_offset = (rt_page_offset - (vertical_page_offset * std::max(static_cast<int>(rt->m_TEX0.TBW), 1))) * frame_psm.pgs.x;
const u32 horizontal_size = std::max(rt->m_unscaled_size.x, ds->m_unscaled_size.x);
const u32 vertical_size = std::max(rt->m_unscaled_size.y, ds->m_unscaled_size.y);
@ -3768,7 +3768,6 @@ void GSRendererHW::Draw()
src->m_texture = rt->m_texture;
src->m_scale = rt->GetScale();
src->m_unscaled_size = rt->m_unscaled_size;
}
target_scale = rt->GetScale();
@ -3884,17 +3883,16 @@ void GSRendererHW::Draw()
// copy of a 16bit source in to this target, make sure it's opaque and not bilinear to reduce false positives.
m_copy_16bit_to_target_shuffle = m_cached_ctx.TEX0.TBP0 != m_cached_ctx.FRAME.Block() && rt->m_32_bits_fmt == true && IsOpaque()
&& !(context->TEX1.MMIN & 1) && !src->m_32_bits_fmt && m_cached_ctx.FRAME.FBMSK;
&& !(context->TEX1.MMIN & 1) && !src->m_32_bits_fmt && m_cached_ctx.FRAME.FBMSK;
// It's not actually possible to do a C16->C16 texture shuffle of B to A as they are the same group
// However you can do it by using C32 and offsetting the target verticies to point to B A, then mask as appropriate.
m_same_group_texture_shuffle = draw_uses_target && (m_cached_ctx.TEX0.PSM & 0xE) == PSMCT32 && (m_cached_ctx.FRAME.PSM & 0x7) == PSMCT16 && (m_vt.m_min.p.x == 8.0f);
// Both input and output are 16 bits and texture was initially 32 bits! Same for the target, Sonic Unleash makes a new target which really is 16bit.
m_texture_shuffle = ((m_same_group_texture_shuffle || (tex_psm.bpp == 16)) && (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) &&
(shuffle_coords || rt->m_32_bits_fmt)) &&
(src->m_32_bits_fmt || m_copy_16bit_to_target_shuffle) &&
(draw_sprite_tex || (m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_index.tail % 6) == 0 && TrianglesAreQuads(true)));
m_texture_shuffle = ((m_same_group_texture_shuffle || (tex_psm.bpp == 16)) && (GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) && (shuffle_coords || rt->m_32_bits_fmt)) &&
(src->m_32_bits_fmt || m_copy_16bit_to_target_shuffle) &&
(draw_sprite_tex || (m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_index.tail % 6) == 0 && TrianglesAreQuads(true)));
if (m_texture_shuffle && IsSplitTextureShuffle(rt->m_TEX0, rt->m_valid))
{
@ -4285,7 +4283,8 @@ void GSRendererHW::Draw()
{
// if the height cache gave a different size to our final size, we need to check if it needs preloading.
// Pirates - Legend of the Black Kat starts a draw of 416, but Z is 448 and it preloads the background.
if (rt->m_drawn_since_read.rempty() && rt->m_dirty.size() > 0 && new_height && (preserve_rt_color || preserve_rt_alpha)) {
if (rt->m_drawn_since_read.rempty() && rt->m_dirty.size() > 0 && new_height && (preserve_rt_color || preserve_rt_alpha))
{
RGBAMask mask;
mask._u32 = preserve_rt_color ? 0x7 : 0;
mask.c.a |= preserve_rt_alpha;
@ -4659,8 +4658,11 @@ void GSRendererHW::Draw()
if (!m_temp_z_full_copy && was_written)
{
GSVector4i dRect = GSVector4i((z_horizontal_offset + (real_rect.x - horizontal_offset)) * ds->m_scale, (z_vertical_offset + (real_rect.y - vertical_offset)) * ds->m_scale, ((z_horizontal_offset + real_rect.z + (1.0f / ds->m_scale)) - horizontal_offset) * ds->m_scale, (z_vertical_offset + (real_rect.w + (1.0f / ds->m_scale) - vertical_offset)) * ds->m_scale);
GSVector4 sRect = GSVector4((real_rect.x * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>(real_rect.y * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), ((real_rect.z + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((real_rect.w + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GSVector4 sRect = GSVector4(
(real_rect.x * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>(real_rect.y * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()),
((real_rect.z + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((real_rect.w + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d rt_vert_offset %d z_horz_offset %d rt_horz_offset %d", s_n, z_vertical_offset, vertical_offset, z_horizontal_offset, horizontal_offset);
g_gs_device->StretchRect(g_texture_cache->GetTemporaryZ(), sRect, ds->m_texture, GSVector4(dRect), ShaderConvert::DEPTH_COPY, false);
@ -4669,7 +4671,10 @@ void GSRendererHW::Draw()
else if (m_temp_z_full_copy)
{
GSVector4i dRect = GSVector4i((ds->m_valid.x + z_horizontal_offset) * ds->m_scale, (ds->m_valid.y + z_vertical_offset) * ds->m_scale, (ds->m_valid.z + z_horizontal_offset + (1.0f / ds->m_scale)) * ds->m_scale, (ds->m_valid.w + z_vertical_offset + (1.0f / ds->m_scale)) * ds->m_scale);
GSVector4 sRect = GSVector4(((ds->m_valid.x + horizontal_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()), static_cast<float>((ds->m_valid.y + vertical_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()), (((ds->m_valid.z + horizontal_offset) + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
GSVector4 sRect = GSVector4(
((ds->m_valid.x + horizontal_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((ds->m_valid.y + vertical_offset) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()),
(((ds->m_valid.z + horizontal_offset) + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetWidth()),
static_cast<float>((ds->m_valid.w + vertical_offset + (1.0f / ds->m_scale)) * ds->m_scale) / static_cast<float>(g_texture_cache->GetTemporaryZ()->GetHeight()));
GL_CACHE("HW: RT in RT Z copy back draw %d z_vert_offset %d z_offset %d", s_n, z_vertical_offset, vertical_offset);
@ -5371,7 +5376,7 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
// Page align test to limit false detections (there is a few).
GSVector4i min_uv = GSVector4i(m_vt.m_min.t.upld(GSVector4::zero()));
ChannelFetch channel = ChannelFetch_NONE;
const GSLocalMemory::psm_t& t_psm = GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM];;
const GSLocalMemory::psm_t& t_psm = GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM];
const GSLocalMemory::psm_t& f_psm = GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM];
GSVector4i block_offset = GSVector4i(min_uv.x / t_psm.bs.x, min_uv.y / t_psm.bs.y).xyxy();
GSVector4i m_r_block_offset = GSVector4i((m_r.x & (f_psm.pgs.x - 1)) / f_psm.bs.x, (m_r.y & (f_psm.pgs.y - 1)) / f_psm.bs.y);
@ -5444,7 +5449,7 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
s[1].U = 16384;
s[0].V = 0;
s[1].V = 16384;
m_r = GSVector4i(0, 0, 1024, 1024);
// We need to count the pages that get shuffled to, some games (like Hitman Blood Money dialogue blur effects) only do half the screen.
@ -5476,7 +5481,7 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
if (rt && rt->m_TEX0.TBP0 == m_cached_ctx.FRAME.Block())
{
const bool req_offset = (m_cached_ctx.CLAMP.WMS != 3 || (m_cached_ctx.CLAMP.MAXU & ~0xF) == 0) &&
(m_cached_ctx.CLAMP.WMT != 3 || (m_cached_ctx.CLAMP.MAXV & ~0x3) == 0);
(m_cached_ctx.CLAMP.WMT != 3 || (m_cached_ctx.CLAMP.MAXV & ~0x3) == 0);
//DevCon.Warning("HW: Draw %d offset %d", s_n, frame_page_offset);
// Offset the frame but clear the draw offset
if (req_offset)
@ -5514,7 +5519,7 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool
new_valid.w = std::max(new_valid.w, offset_height);
rt->UpdateValidity(new_valid, true);
}
m_vertex.head = m_vertex.tail = m_vertex.next = 2;
m_index.tail = 2;
@ -5568,7 +5573,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
#endif
// If the colour is modulated to zero or we're not using a texture and the color is zero, we can replace any Cs with 0
if ((!PRIM->TME || m_cached_ctx.TEX0.TFX != TFX_DECAL) && (!PRIM->FGE || m_draw_env->FOGCOL.U32[0] == 0) &&
if ((!PRIM->TME || m_cached_ctx.TEX0.TFX != TFX_DECAL) && (!PRIM->FGE || m_draw_env->FOGCOL.U32[0] == 0) &&
((m_vt.m_max.c == GSVector4i::zero()).mask() & 0xfff) == 0xfff)
{
// If using modulate or is HIGHLIGHT by the vertex alpha is zero, we should be safe to kill it.
@ -5739,7 +5744,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
// Condition 4: If it's tex in fb draw and there's no overlap prefer sw blend, fb is already being read.
const bool prefer_sw_blend = (features.texture_barrier && m_conf.require_full_barrier) || (m_conf.require_one_barrier && (no_prim_overlap || m_channel_shuffle)) || m_conf.ps.shuffle || (no_prim_overlap && (m_conf.tex == m_conf.rt));
const bool free_blend = blend_non_recursive // Free sw blending, doesn't require barriers or reading fb
|| accumulation_blend; // Mix of hw/sw blending
|| accumulation_blend; // Mix of hw/sw blending
// Warning no break on purpose
// Note: the [[fallthrough]] attribute tell compilers not to complain about not having breaks.
@ -5795,7 +5800,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
else
{
const bool ad_second_pass = blend_multi_pass_support && alpha_c1_high_no_rta_correct && COLCLAMP.CLAMP &&
(blend_flag & (BLEND_HW3 | BLEND_HW5 | BLEND_HW6 | BLEND_HW7 | BLEND_HW9));
(blend_flag & (BLEND_HW3 | BLEND_HW5 | BLEND_HW6 | BLEND_HW7 | BLEND_HW9));
switch (GSConfig.AccurateBlendingUnit)
{
@ -6137,7 +6142,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
new_rt_alpha_scale = true;
alpha_c1_high_no_rta_correct = false;
m_conf.ps.rta_correction = rt->m_rt_alpha_scale;
}
@ -6307,9 +6312,9 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo
// Remove second color output when unused. Works around bugs in some drivers (e.g. Intel).
m_conf.ps.no_color1 = !GSDevice::IsDualSourceBlendFactor(m_conf.blend.src_factor) &&
!GSDevice::IsDualSourceBlendFactor(m_conf.blend.dst_factor) &&
!GSDevice::IsDualSourceBlendFactor(m_conf.blend_multi_pass.blend.src_factor) &&
!GSDevice::IsDualSourceBlendFactor(m_conf.blend_multi_pass.blend.dst_factor);
!GSDevice::IsDualSourceBlendFactor(m_conf.blend.dst_factor) &&
!GSDevice::IsDualSourceBlendFactor(m_conf.blend_multi_pass.blend.src_factor) &&
!GSDevice::IsDualSourceBlendFactor(m_conf.blend_multi_pass.blend.dst_factor);
}
// Notify the shader that it needs to invert rounding
@ -6380,9 +6385,9 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
// we keep the shader clamp. See #5851 on github, and the note in Draw().
[[maybe_unused]] static constexpr const char* clamp_modes[] = {"REPEAT", "CLAMP", "REGION_CLAMP", "REGION_REPEAT"};
const bool redundant_wms = IsRedundantClamp(m_cached_ctx.CLAMP.WMS, m_cached_ctx.CLAMP.MINU,
m_cached_ctx.CLAMP.MAXU, m_cached_ctx.TEX0.TW);
m_cached_ctx.CLAMP.MAXU, m_cached_ctx.TEX0.TW);
const bool redundant_wmt = IsRedundantClamp(m_cached_ctx.CLAMP.WMT, m_cached_ctx.CLAMP.MINV,
m_cached_ctx.CLAMP.MAXV, m_cached_ctx.TEX0.TH);
m_cached_ctx.CLAMP.MAXV, m_cached_ctx.TEX0.TH);
const u8 wms = EffectiveClamp(m_cached_ctx.CLAMP.WMS, !tex->m_target && (source_region.HasX() || redundant_wms));
const u8 wmt = EffectiveClamp(m_cached_ctx.CLAMP.WMT, !tex->m_target && (source_region.HasY() || redundant_wmt));
const bool complex_wms_wmt = !!((wms | wmt) & 2) || target_region;
@ -6394,7 +6399,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
const bool need_mipmap = IsMipMapDraw();
const bool shader_emulated_sampler = tex->m_palette || (tex->m_target && !m_conf.ps.shuffle && cpsm.fmt != 0) ||
complex_wms_wmt || psm.depth || target_region;
complex_wms_wmt || psm.depth || target_region;
const bool can_trilinear = !tex->m_palette && !tex->m_target && !m_conf.ps.shuffle;
const bool trilinear_manual = need_mipmap && GSConfig.HWMipmap;
@ -6667,7 +6672,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
// This "fixes" a lot of the rainbow garbage in games when upscaling (and xenosaga shadows + VP2 forest seem quite happy).
// Note that this is done on the original texture scale, during upscales it can mess up otherwise.
const GSVector4 region_clamp_offset = GSVector4::cxpr(0.5f, 0.5f, 0.1f, 0.1f) + (GSVector4::cxpr(0.1f, 0.1f, 0.0f, 0.0f) * tex->GetScale());
const GSVector4 region_clamp = (GSVector4(clamp) + region_clamp_offset) / WH.xyxy();
if (wms >= CLAMP_REGION_CLAMP)
{
@ -6680,7 +6685,7 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
m_conf.cb_ps.MinMax.w = (wmt == CLAMP_REGION_CLAMP && !m_conf.ps.depth_fmt) ? region_clamp.w : region_repeat.w;
}
}
if (trilinear_manual)
{
m_conf.cb_ps.LODParams.x = static_cast<float>(m_context->TEX1.K) / 16.0f;
@ -6711,8 +6716,8 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt,
// Remove linear from trilinear, since we're doing the bilinear in the shader, and we only want this for mip selection.
m_conf.sampler.triln = (trilinear >= static_cast<u8>(GS_MIN_FILTER::Linear_Mipmap_Nearest)) ?
(trilinear - static_cast<u8>(GS_MIN_FILTER::Nearest_Mipmap_Nearest)) :
0;
(trilinear - static_cast<u8>(GS_MIN_FILTER::Nearest_Mipmap_Nearest)) :
0;
}
else
{
@ -6933,8 +6938,8 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
static_cast<int>(std::ceil(static_cast<float>(copy_size.y) * scale)));
src_copy.reset(src_target->m_texture->IsDepthStencil() ?
g_gs_device->CreateDepthStencil(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), false) :
g_gs_device->CreateRenderTarget(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), true, true));
g_gs_device->CreateDepthStencil(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), false) :
g_gs_device->CreateRenderTarget(scaled_copy_size.x, scaled_copy_size.y, src_target->m_texture->GetFormat(), true, true));
if (!src_copy) [[unlikely]]
{
Console.Error("HW: Failed to allocate %dx%d texture for hazard copy", scaled_copy_size.x, scaled_copy_size.y);
@ -6961,8 +6966,8 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c
// causing bleeding into the edges of the downsampled texture.
const u32 downsample_factor = static_cast<u32>(src_target->GetScale());
const GSVector2i clamp_min = (GSConfig.UserHacks_HalfPixelOffset < GSHalfPixelOffset::Native) ?
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
GSVector2i(0, 0) :
GSVector2i(downsample_factor, downsample_factor);
GSVector4i copy_rect = tmm.coverage;
if (target_region)
{
@ -7212,7 +7217,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
m_conf.ps.scanmsk = env.SCANMSK.MSK;
m_conf.rt = rt ? rt->m_texture : nullptr;
m_conf.ds = ds ? (m_using_temp_z ? g_texture_cache->GetTemporaryZ() : ds->m_texture) : nullptr;
pxAssert(!ds || !rt || (m_conf.ds->GetSize().x == m_conf.rt->GetSize().x && m_conf.ds->GetSize().y == m_conf.rt->GetSize().y));
// Z setup has to come before channel shuffle
@ -7802,12 +7807,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
const int unscaled_y = rt_or_ds ? rt_or_ds->GetUnscaledHeight() : 0;
sx = 2.0f / (unscaled_x << 4);
sy = 2.0f / (unscaled_y << 4);
if (GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::NativeWTexOffset)
{
ox2 = (-1.0f / (unscaled_x * rtscale));
oy2 = (-1.0f / (unscaled_y * rtscale));
// Having the vertex negatively offset is a common thing for copying sprites but this causes problems when upscaling, so we need to further adjust the offset.
// This kinda screws things up when using ST, so let's not.
if (m_vt.m_primclass == GS_SPRITE_CLASS && rtscale > 1.0f && (tex && PRIM->FST))
@ -8127,7 +8132,7 @@ GSRendererHW::CLUTDrawTestResult GSRendererHW::PossibleCLUTDraw()
const float draw_width = (m_vt.m_max.p.x - m_vt.m_min.p.x);
const float draw_height = (m_vt.m_max.p.y - m_vt.m_min.p.y);
const bool valid_size = ((draw_width >= min_clut_width || draw_height >= min_clut_height))
&& (((draw_width < page_width && draw_height <= page_height) || (draw_width == page_width)) && draw_divder_match); // Make sure draw is multiples of 8 wide (AC5 midetection).
&& (((draw_width < page_width && draw_height <= page_height) || (draw_width == page_width)) && draw_divder_match); // Make sure draw is multiples of 8 wide (AC5 midetection).
// Make sure the draw hits the next CLUT and it's marked as invalid (kind of a sanity check).
// We can also allow draws which are of a sensible size within the page, as they could also be CLUT draws (or gradients for the CLUT).
@ -8257,7 +8262,7 @@ bool GSRendererHW::CanUseSwPrimRender(bool no_rt, bool no_ds, bool draw_sprite_t
{
GSTextureCache::Target* dst_target = g_texture_cache->GetTargetWithSharedBits(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.PSM);
if (dst_target && dst_target->m_dirty.empty() && ((!(GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x7)) || dst_target->m_valid_rgb) &&
if (dst_target && dst_target->m_dirty.empty() && ((!(GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x7)) || dst_target->m_valid_rgb) &&
((!(GSUtil::GetChannelMask(m_cached_ctx.FRAME.PSM) & 0x8)) || (dst_target->m_valid_alpha_low && dst_target->m_valid_alpha_high)))
return false;
}
@ -8355,12 +8360,11 @@ bool GSRendererHW::DetectStripedDoubleClear(bool& no_rt, bool& no_ds)
{
const bool single_page_offset =
std::abs(static_cast<int>(m_cached_ctx.FRAME.FBP) - static_cast<int>(m_cached_ctx.ZBUF.ZBP)) == 1;
const bool z_is_frame = (m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP ||
(m_cached_ctx.FRAME.FBW > 1 && single_page_offset)) && // GT4O Public Beta
!m_cached_ctx.ZBUF.ZMSK &&
(m_cached_ctx.FRAME.PSM & 0x30) != (m_cached_ctx.ZBUF.PSM & 0x30) &&
(m_cached_ctx.FRAME.PSM & 0xF) == (m_cached_ctx.ZBUF.PSM & 0xF) && m_vt.m_eq.z == 1 &&
m_vertex.buff[1].XYZ.Z == m_vertex.buff[1].RGBAQ.U32[0];
const bool z_is_frame = (m_cached_ctx.FRAME.FBP == m_cached_ctx.ZBUF.ZBP || (m_cached_ctx.FRAME.FBW > 1 && single_page_offset)) && // GT4O Public Beta
!m_cached_ctx.ZBUF.ZMSK &&
(m_cached_ctx.FRAME.PSM & 0x30) != (m_cached_ctx.ZBUF.PSM & 0x30) &&
(m_cached_ctx.FRAME.PSM & 0xF) == (m_cached_ctx.ZBUF.PSM & 0xF) && m_vt.m_eq.z == 1 &&
m_vertex.buff[1].XYZ.Z == m_vertex.buff[1].RGBAQ.U32[0];
// Z and color must be constant and the same and must be drawing strips.
if (!z_is_frame || m_vt.m_eq.rgba != 0xFFFF)
@ -8874,7 +8878,7 @@ void GSRendererHW::ClearGSLocalMemory(const GSOffset& off, const GSVector4i& r,
else if (format == GSLocalMemory::PSM_FMT_16)
{
const u16 converted_color = ((vert_color >> 16) & 0x8000) | ((vert_color >> 9) & 0x7C00) |
((vert_color >> 6) & 0x7E0) | ((vert_color >> 3) & 0x1F);
((vert_color >> 6) & 0x7E0) | ((vert_color >> 3) & 0x1F);
const GSVector4i vcolor = GSVector4i::broadcast16(converted_color);
const u32 iterations_per_page = (pages_wide * pixels_per_page) / 8;
pxAssert((off.bp() & (GS_BLOCKS_PER_PAGE - 1)) == 0);
@ -8997,27 +9001,27 @@ bool GSRendererHW::OI_BlitFMV(GSTextureCache::Target* _rt, GSTextureCache::Sourc
bool GSRendererHW::AreAnyPixelsDiscarded() const
{
return ((m_draw_env->SCANMSK.MSK & 2) || // skipping rows
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.AFAIL != AFAIL_FB_ONLY) || // testing alpha (might discard some pixels)
m_cached_ctx.TEST.DATE); // reading alpha
(m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.AFAIL != AFAIL_FB_ONLY) || // testing alpha (might discard some pixels)
m_cached_ctx.TEST.DATE); // reading alpha
}
bool GSRendererHW::IsDiscardingDstColor()
{
return ((!PRIM->ABE || IsOpaque() || m_context->ALPHA.IsBlack()) && // no blending or writing black
!AreAnyPixelsDiscarded() && (m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) == 0); // no channels masked
!AreAnyPixelsDiscarded() && (m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) == 0); // no channels masked
}
bool GSRendererHW::IsDiscardingDstRGB()
{
return ((!PRIM->ABE || IsOpaque() || m_context->ALPHA.IsBlack() || !m_context->ALPHA.IsCdInBlend()) && // no blending or writing black
((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFFFFFFu) == 0); // RGB isn't masked
((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFFFFFFu) == 0); // RGB isn't masked
}
bool GSRendererHW::IsDiscardingDstAlpha() const
{
return ((!PRIM->ABE || m_context->ALPHA.C != 1) && // not using Ad
((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFF000000u) == 0) && // alpha isn't masked
(!m_cached_ctx.TEST.ATE || !(m_cached_ctx.TEST.ATST == ATST_NEVER && m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY && m_cached_ctx.FRAME.PSM == PSMCT32)); // No alpha test or no rbg only
((m_cached_ctx.FRAME.FBMSK & GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].fmsk) & 0xFF000000u) == 0) && // alpha isn't masked
(!m_cached_ctx.TEST.ATE || !(m_cached_ctx.TEST.ATST == ATST_NEVER && m_cached_ctx.TEST.AFAIL == AFAIL_RGB_ONLY && m_cached_ctx.FRAME.PSM == PSMCT32)); // No alpha test or no rbg only
}
// Like PrimitiveCoversWithoutGaps but with texture coordinates.
@ -9068,12 +9072,12 @@ bool GSRendererHW::TextureCoversWithoutGapsNotEqual()
const int this_start_U = v[i].U;
const int last_start_U = v[i - 2].U;
const int dtU = v[i + 1].U - v[i].U;
const int dtU = v[i + 1].U - v[i].U;
if (this_start_U < last_start_U)
{
if (std::abs(dtU - last_start_U) >= 16 || std::abs(this_start_U) >= 16)
{;
{
return false;
}
}
@ -9440,7 +9444,7 @@ void GSRendererHW::EndHLEHardwareDraw(bool force_copy_on_hazard /* = false */)
return;
}
const GSVector4i copy_rect = config.drawarea.rintersect(src->GetRect());
const GSVector4i copy_rect = config.drawarea.rintersect(src->GetRect());
g_gs_device->CopyRect(src, copy, copy_rect - copy_rect.xyxy(), copy_rect.x, copy_rect.y);
config.tex = copy;
}
@ -9449,8 +9453,8 @@ void GSRendererHW::EndHLEHardwareDraw(bool force_copy_on_hazard /* = false */)
// Drop color1 if dual-source is not being used.
config.ps.no_color = !config.rt;
config.ps.no_color1 = !config.rt || !config.blend.enable ||
(!GSDevice::IsDualSourceBlendFactor(config.blend.src_factor) &&
!GSDevice::IsDualSourceBlendFactor(config.blend.dst_factor));
(!GSDevice::IsDualSourceBlendFactor(config.blend.src_factor) &&
!GSDevice::IsDualSourceBlendFactor(config.blend.dst_factor));
g_gs_device->RenderHW(m_conf);

View File

@ -348,7 +348,7 @@ GSVector4i GSTextureCache::TranslateAlignedRectByPage(u32 tbp, u32 tebp, u32 tbw
const int rect_pages = std::max(((in_rect.width() / t_psm.pgs.x) % src_pgw) + ((in_rect.height() / t_psm.pgs.y) * src_pgw), 1);
page_offset += rect_offset;
in_rect -= GSVector4i(horizontal_offset * t_psm.pgs.x, vertical_offset * t_psm.pgs.y).xyxy();
if (sbw == 0) // Intentionally check this separately
{
// BW == 0 loops vertically on the first page. So just copy the whole page vertically.
@ -391,7 +391,7 @@ GSVector4i GSTextureCache::TranslateAlignedRectByPage(u32 tbp, u32 tebp, u32 tbw
}
else
{
// Fills full length, so count pages based on the width, adjust rect to fill original rect.
// Battle Assault 3 does a move with BW 7 instead of 8 and does 448x512, instead of 512x448. Same result, but confusing for us.
@ -1334,7 +1334,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
continue;
const bool width_match = (std::max(64U, bw * 64U) >> GSLocalMemory::m_psm[psm].info.pageShiftX()) ==
(std::max(64U, t->m_TEX0.TBW * 64U) >> GSLocalMemory::m_psm[t->m_TEX0.PSM].info.pageShiftX());
(std::max(64U, t->m_TEX0.TBW * 64U) >> GSLocalMemory::m_psm[t->m_TEX0.PSM].info.pageShiftX());
if (bp == t->m_TEX0.TBP0 && !t->m_dirty.empty() && GSUtil::GetChannelMask(psm) == GSUtil::GetChannelMask(t->m_TEX0.PSM) && GSRendererHW::GetInstance()->m_draw_transfers.size() > 0)
{
@ -1461,7 +1461,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
{
rect_clean = false;
if(!dirty_rect.rintersect(t->m_valid).eq(t->m_valid) || GSUtil::GetChannelMask(t->m_TEX0.PSM) != t->m_dirty.GetDirtyChannels())
if (!dirty_rect.rintersect(t->m_valid).eq(t->m_valid) || GSUtil::GetChannelMask(t->m_TEX0.PSM) != t->m_dirty.GetDirtyChannels())
partial |= !new_rect.rintersect(dirty_rect).eq(new_rect) || dirty_rect.eq(new_rect);
else // Nothing is valid anymore, kill it.
{
@ -1484,7 +1484,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const u32 channels = t->m_dirty.GetDirtyChannels() & channel_mask;
const bool dirty_overlap = !t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size).rintersect(new_rect).rempty();
// If the source is reading the rt, make sure it's big enough.
if (!possible_shuffle && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM)&& real_fmt_match)
if (!possible_shuffle && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && real_fmt_match)
{
// Be careful if a new texture has been uploaded that expands the current one (Valkyrie Profile 2 does this)
GSVector4i dirty_rect = (t->m_dirty.size() > 0 && bw == t->m_TEX0.TBW) ? t->m_dirty.GetTotalRect(t->m_TEX0, GSVector2i(new_rect.z, new_rect.w)) : GSVector4i(GSVector4(t->m_valid) * GSVector4(2));
@ -1595,7 +1595,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const u32 color_psm = ((psm & 0x30) == 0x30) ? (psm & ~0x30) : psm;
const u32 tex_color_psm = ((t->m_TEX0.PSM & 0x30) == 0x30) ? (t->m_TEX0.PSM & ~0x30) : t->m_TEX0.PSM;
const bool can_convert = (GSUtil::HasCompatibleBits(psm, t_psm) && ((bw == t->m_TEX0.TBW) || (bw <= 1 && req_rect.w < GSLocalMemory::m_psm[psm].pgs.y))) ||
(possible_shuffle && ((bw == t->m_TEX0.TBW) || (bw == (t->m_TEX0.TBW * 2) || bw <= 2)) && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32);
(possible_shuffle && ((bw == t->m_TEX0.TBW) || (bw == (t->m_TEX0.TBW * 2) || bw <= 2)) && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32);
if (t->m_was_dst_matched)
{
@ -1608,7 +1608,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
for (Target* dst_match : m_dst[DepthStencil])
{
// Be careful of dirty overlap on the targets, we don't really want dirty data.
if (dst_match->m_TEX0.TBP0 != t->m_TEX0.TBP0 || !dst_match->m_valid_rgb ||(!dst_match->m_dirty.empty() && !dst_match->m_dirty.GetTotalRect(dst_match->m_TEX0, dst_match->m_unscaled_size).rintersect(block_boundary_rect).rempty()))
if (dst_match->m_TEX0.TBP0 != t->m_TEX0.TBP0 || !dst_match->m_valid_rgb || (!dst_match->m_dirty.empty() && !dst_match->m_dirty.GetTotalRect(dst_match->m_TEX0, dst_match->m_unscaled_size).rintersect(block_boundary_rect).rempty()))
continue;
if (!CopyRGBFromDepthToColor(t, dst_match))
@ -1684,8 +1684,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
// Make sure the texture actually is INSIDE the RT, it's possibly not valid if it isn't.
// Also check BP >= TBP, create source isn't equpped to expand it backwards and all data comes from the target. (GH3)
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets &&
(GSLocalMemory::m_psm[color_psm].bpp >= 16 || (/*possible_shuffle &&*/ GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp >= 16)) && // Channel shuffles or non indexed lookups.
t->m_age <= 1 && (!found_t || t->m_last_draw > dst->m_last_draw) /*&& CanTranslate(bp, bw, psm, block_boundary_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW)*/)
(GSLocalMemory::m_psm[color_psm].bpp >= 16 || (/*possible_shuffle &&*/ GSLocalMemory::m_psm[color_psm].bpp == 8 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp >= 16)) && // Channel shuffles or non indexed lookups.
t->m_age <= 1 && (!found_t || t->m_last_draw > dst->m_last_draw) /*&& CanTranslate(bp, bw, psm, block_boundary_rect, t->m_TEX0.TBP0, t->m_TEX0.PSM, t->m_TEX0.TBW)*/)
{
u32 rt_tbw = std::max(1U, t->m_TEX0.TBW);
u32 horz_page_offset = ((bp - t->m_TEX0.TBP0) >> 5) % rt_tbw;
@ -1694,18 +1694,20 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
continue;
if (GSLocalMemory::m_psm[color_psm].bpp == 16 && GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp == 32 && bw != 1 &&
((t->m_TEX0.TBW < (horz_page_offset + ((block_boundary_rect.z + GSLocalMemory::m_psm[psm].pgs.x - 1) / GSLocalMemory::m_psm[psm].pgs.x)) ||
(t->m_TEX0.TBW != bw && block_boundary_rect.w > GSLocalMemory::m_psm[psm].pgs.y))))
((t->m_TEX0.TBW < (horz_page_offset + ((block_boundary_rect.z + GSLocalMemory::m_psm[psm].pgs.x - 1) / GSLocalMemory::m_psm[psm].pgs.x)) ||
(t->m_TEX0.TBW != bw && block_boundary_rect.w > GSLocalMemory::m_psm[psm].pgs.y))))
{
DbgCon.Warning("BP %x - 16bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
continue;
}
// Keep note that 2 bw is basically 1 normal page, as bw is in 64 pixels, and 8bit pages are 128 pixels wide, aka 2 bw.
// Also check for 4HH/HL and 8H which use the alpha channel, if the page order is wrong this can cause problems as well (Jak X font).
else if (!possible_shuffle && GSLocalMemory::m_psm[psm].trbpp <= 8 && (GSUtil::GetChannelMask(t->m_TEX0.PSM) != 0xF ||
((GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp != 16 || GSLocalMemory::m_psm[psm].bpp < 16) && (!(block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y &&
((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) <= t->m_TEX0.TBW) &&
!(((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) == rt_tbw)))))
else if (!possible_shuffle && GSLocalMemory::m_psm[psm].trbpp <= 8 &&
(GSUtil::GetChannelMask(t->m_TEX0.PSM) != 0xF ||
((GSLocalMemory::m_psm[t->m_TEX0.PSM].bpp != 16 || GSLocalMemory::m_psm[psm].bpp < 16) &&
(!(block_boundary_rect.w <= GSLocalMemory::m_psm[psm].pgs.y &&
((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) <= t->m_TEX0.TBW) &&
!(((GSLocalMemory::m_psm[psm].bpp == 32) ? bw : ((bw + 1) / 2)) == rt_tbw)))))
{
DbgCon.Warning("BP %x - 8bit bad match for target bp %x bw %d src %d format %d", bp, t->m_TEX0.TBP0, t->m_TEX0.TBW, bw, t->m_TEX0.PSM);
continue;
@ -1870,9 +1872,9 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const GSOffset offset(GSLocalMemory::m_psm[src_psm].info, bp, bw, psm);
const u32 offset_bp = offset.bn(region.GetMinX(), region.GetMinY());
if (bp < t->m_TEX0.TBP0 && region.HasX() && region.HasY() &&
(region.GetMinX() & (page_size.x - 1)) == 0 && (region.GetMinY() & (page_size.y - 1)) == 0 &&
(offset.bn(region.GetMinX(), region.GetMinY()) == t->m_TEX0.TBP0 ||
((offset_bp >= t->m_TEX0.TBP0) && ((((offset_bp - t->m_TEX0.TBP0) >> 5) % bw) + (rect.width() / page_size.x)) <= bw)))
(region.GetMinX() & (page_size.x - 1)) == 0 && (region.GetMinY() & (page_size.y - 1)) == 0 &&
(offset.bn(region.GetMinX(), region.GetMinY()) == t->m_TEX0.TBP0 ||
((offset_bp >= t->m_TEX0.TBP0) && ((((offset_bp - t->m_TEX0.TBP0) >> 5) % bw) + (rect.width() / page_size.x)) <= bw)))
{
GL_CACHE("TC: Target 0x%x detected in front of TBP 0x%x with %d,%d offset (%d pages)",
t->m_TEX0.TBP0, TEX0.TBP0, region.GetMinX(), region.GetMinY(),
@ -2292,7 +2294,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
if (bp == t->m_TEX0.TBP0)
{
bool can_use = true;
if (dst && ((GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw) && dst->m_TEX0.TBP0 <= bp))
{
DevCon.Warning("Ignoring target at %x as one at %x is newer", t->m_TEX0.TBP0, dst->m_TEX0.TBP0);
@ -2452,7 +2454,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
const GSVector4i dirty_rect = t->m_dirty.empty() ? GSVector4i::zero() : t->m_dirty.GetTotalRect(t->m_TEX0, t->m_unscaled_size);
const bool all_dirty = dirty_rect.eq(t->m_valid);
if (!is_shuffle && !dirty_rect.rempty() && (!preserve_alpha && !preserve_rgb) && (GSState::s_n - 3) > t->m_last_draw)
{
GL_INS("TC: Deleting RT BP 0x%x BW %d PSM %s due to dirty areas not preserved (Likely change in target)", t->m_TEX0.TBP0, t->m_TEX0.TBW, GSUtil::GetPSMName(t->m_TEX0.PSM));
@ -2627,7 +2629,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
{
calcRescale(dst);
GSTexture* tex = type == RenderTarget ? g_gs_device->CreateRenderTarget(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::Color, clear) :
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
if (!tex)
return nullptr;
@ -2680,8 +2682,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
new_scaled_size = ScaleRenderTargetSize(dst->m_unscaled_size, dst->m_scale);
dRect = (GSVector4(dst->m_valid) * GSVector4(dst->m_scale)).ceil();
GSVector4 source_rect = GSVector4(static_cast<float>(dst->m_valid.x) / static_cast<float>(dst->m_unscaled_size.x), static_cast<float>(dst->m_valid.y) / static_cast<float>(dst->m_unscaled_size.y),
static_cast<float>(dst->m_valid.z) / static_cast<float>(dst->m_unscaled_size.x), static_cast<float>(dst->m_valid.w) / static_cast<float>(dst->m_unscaled_size.y));
GSVector4 source_rect = GSVector4(
static_cast<float>(dst->m_valid.x) / static_cast<float>(dst->m_unscaled_size.x),
static_cast<float>(dst->m_valid.y) / static_cast<float>(dst->m_unscaled_size.y),
static_cast<float>(dst->m_valid.z) / static_cast<float>(dst->m_unscaled_size.x),
static_cast<float>(dst->m_valid.w) / static_cast<float>(dst->m_unscaled_size.y));
if (!is_shuffle || GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16)
{
if (scale_down)
@ -2727,7 +2732,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
else
{
GSTexture* tex = type == RenderTarget ? g_gs_device->CreateRenderTarget(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::Color, clear) :
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
if (!tex)
return nullptr;
@ -2748,7 +2753,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
else
{
GSTexture* tex = type == RenderTarget ? g_gs_device->CreateRenderTarget(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::Color, clear) :
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
g_gs_device->CreateDepthStencil(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::DepthStencil, clear);
if (!tex)
return nullptr;
@ -2769,7 +2774,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
// New format or doing a shuffle to a 32bit target that used to be 16bit
if ((!is_shuffle && (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp != GSLocalMemory::m_psm[TEX0.PSM].bpp || GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth)) ||
if ((!is_shuffle && (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp != GSLocalMemory::m_psm[TEX0.PSM].bpp || GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth)) ||
(is_shuffle && GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16))
{
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].depth != GSLocalMemory::m_psm[TEX0.PSM].depth || dst->m_TEX0.TBW != TEX0.TBW)
@ -2835,8 +2840,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 16) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
ShaderConvert::RGBA8_TO_FLOAT24;
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
ShaderConvert::RGBA8_TO_FLOAT24;
g_gs_device->StretchRect(dst_match->m_texture, GSVector4(0, 0, 1, 1),
dst->m_texture, GSVector4(dst->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false);
@ -2859,10 +2864,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
// Unfortunately, we still have an alpha channel to preserve, and we can't clear RGB...
// So, create a new target, clear/preload it, and copy RGB in.
GSTexture* tex = (type == RenderTarget) ?
g_gs_device->CreateRenderTarget(dst->m_texture->GetWidth(),
dst->m_texture->GetHeight(), GSTexture::Format::Color, true) :
g_gs_device->CreateDepthStencil(dst->m_texture->GetWidth(),
dst->m_texture->GetHeight(), GSTexture::Format::DepthStencil, true);
g_gs_device->CreateRenderTarget(dst->m_texture->GetWidth(), dst->m_texture->GetHeight(), GSTexture::Format::Color, true) :
g_gs_device->CreateDepthStencil(dst->m_texture->GetWidth(), dst->m_texture->GetHeight(), GSTexture::Format::DepthStencil, true);
if (!tex)
return nullptr;
@ -2943,7 +2946,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
// If the format is completely different, but it's the same location, it's likely just overwriting it, so get rid.
// Make sure it's not currently in use, that could be bad.
if (!is_shuffle && (!ds || (ds != t)) &&
if (!is_shuffle && (!ds || (ds != t)) &&
t->m_TEX0.TBW != TEX0.TBW && TEX0.TBW != 1 && !preserve_rgb && min_rect.w > GSLocalMemory::m_psm[t->m_TEX0.PSM].pgs.y)
{
if (src && src->m_target && src->m_from_target == t && src->m_target_direct)
@ -3017,7 +3020,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
// If we don't need A, and the existing target doesn't have valid alpha, don't bother converting it.
const bool has_alpha = dst_match->HasValidAlpha();
const bool preserve_target = (preserve_rgb || (preserve_alpha && has_alpha)) ||
!draw_rect.rintersect(dst_match->m_valid).eq(dst_match->m_valid);
!draw_rect.rintersect(dst_match->m_valid).eq(dst_match->m_valid);
bool half_width = false;
@ -3069,7 +3072,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
GL_CACHE("TC: Lookup Target(Depth) %dx%d, hit Color (0x%x, TBW %d, %s was %s)", new_size.x, new_size.y,
bp, TEX0.TBW, GSUtil::GetPSMName(TEX0.PSM), GSUtil::GetPSMName(dst_match->m_TEX0.PSM));
shader = (fmt_16_bits) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
(ShaderConvert)(static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT32) + psm_s.fmt);
(ShaderConvert)(static_cast<int>(ShaderConvert::RGBA8_TO_FLOAT32) + psm_s.fmt);
}
else
{
@ -3402,7 +3405,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
}
}
const GSVector4i dst_valid = dst->m_valid.rempty() ? GSVector4i::loadh(valid_size) : dst->m_valid;
u32 dst_end_block = GSLocalMemory::GetEndBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, dst_valid);
if (dst_end_block < dst->m_TEX0.TBP0)
@ -3433,7 +3436,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
// Probably best we don't poke the beast if it's being used as the current source.
if (src && src->m_target_direct && src->m_from_target == t)
continue;
InvalidateSourcesFromTarget(t);
i = list.erase(j);
delete t;
@ -3541,7 +3544,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
GL_INS("TC: RT double buffer copy from FBP 0x%x, %dx%d => %d,%d", t->m_TEX0.TBP0, copy_width, copy_height, 0, dst_offset_scaled_height);
// Clear the dirty first
t->Update();
dst->Update();
@ -3621,11 +3624,12 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
t->m_was_dst_matched = true;
dst->ResizeTexture(t->m_unscaled_size.x, t->m_unscaled_size.y);
const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 16) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 : ShaderConvert::RGBA8_TO_FLOAT24;
g_gs_device->StretchRect(t->m_texture, GSVector4(0,0,1,1),
const ShaderConvert shader = (GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 16) ? ShaderConvert::RGB5A1_TO_FLOAT16 :
(GSLocalMemory::m_psm[dst->m_TEX0.PSM].trbpp == 32) ? ShaderConvert::RGBA8_TO_FLOAT32 :
ShaderConvert::RGBA8_TO_FLOAT24;
g_gs_device->StretchRect(t->m_texture, GSVector4(0, 0, 1, 1),
dst->m_texture, GSVector4(t->GetUnscaledRect()) * GSVector4(dst->GetScale()), shader, false);
break;
@ -3658,10 +3662,8 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
t->ResizeValidity(t->m_valid);
GSTexture* tex = (t->m_type == RenderTarget) ?
g_gs_device->CreateRenderTarget(t->m_texture->GetWidth(),
t->m_texture->GetHeight(), GSTexture::Format::Color, true) :
g_gs_device->CreateDepthStencil(t->m_texture->GetWidth(),
t->m_texture->GetHeight(), GSTexture::Format::DepthStencil, true);
g_gs_device->CreateRenderTarget(t->m_texture->GetWidth(), t->m_texture->GetHeight(), GSTexture::Format::Color, true) :
g_gs_device->CreateDepthStencil(t->m_texture->GetWidth(), t->m_texture->GetHeight(), GSTexture::Format::DepthStencil, true);
if (tex)
{
g_gs_device->CopyRect(t->m_texture, tex, GSVector4i(0, height_adjust * t->m_scale, t->m_texture->GetWidth(), t->m_texture->GetHeight()), 0, 0);
@ -3702,7 +3704,6 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
continue;
}
}
}
i++;
}
@ -3937,8 +3938,8 @@ float GSTextureCache::ConvertColorToDepth(u32 c, ShaderConvert convert)
{
case ShaderConvert::RGB5A1_TO_FLOAT16:
return static_cast<float>(((c & 0xF8u) >> 3) | (((c >> 8) & 0xF8u) << 2) | (((c >> 16) & 0xF8u) << 7) |
(((c >> 24) & 0x80u) << 8)) *
mult;
(((c >> 24) & 0x80u) << 8)) *
mult;
case ShaderConvert::RGBA8_TO_FLOAT16:
return static_cast<float>(c & 0x0000FFFF) * mult;
@ -4185,7 +4186,7 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
if (type == DepthStencil && t->m_TEX0.TBP0 < start_bp && t->m_end_block > start_bp)
{
const GSVector4i masked_valid = GSVector4i(t->m_valid.x, t->m_valid.y, t->m_valid.z & ~1, t->m_valid.w & ~1);
const u32 reduced_endblock = GSLocalMemory::GetEndBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, masked_valid);
const u32 reduced_endblock = GSLocalMemory::GetEndBlockAddress(t->m_TEX0.TBP0, t->m_TEX0.TBW, t->m_TEX0.PSM, masked_valid);
if (reduced_endblock <= start_bp)
{
@ -5040,8 +5041,8 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
if (SBP == DBP && (!(GSVector4i(sx, sy, sx + w, sy + h).rintersect(GSVector4i(dx, dy, dx + w, dy + h))).rempty() || renderer_is_directx))
{
GSTexture* tmp_texture = src->m_texture->IsDepthStencil() ?
g_gs_device->CreateDepthStencil(src->m_texture->GetWidth(), src->m_texture->GetHeight(), src->m_texture->GetFormat(), false) :
g_gs_device->CreateRenderTarget(src->m_texture->GetWidth(), src->m_texture->GetHeight(), src->m_texture->GetFormat(), false);
g_gs_device->CreateDepthStencil(src->m_texture->GetWidth(), src->m_texture->GetHeight(), src->m_texture->GetFormat(), false) :
g_gs_device->CreateRenderTarget(src->m_texture->GetWidth(), src->m_texture->GetHeight(), src->m_texture->GetFormat(), false);
if (!tmp_texture)
{
Console.Error("(HW Move) Failed to allocate temporary %dx%d texture on HW move", w, h);
@ -5109,7 +5110,6 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
}
const GSVector4 src_rect = GSVector4(scaled_sx, scaled_sy, scaled_sx + scaled_w, scaled_sy + scaled_h) / (GSVector4(src->m_texture->GetSize()).xyxy());
g_gs_device->StretchRect(src->m_texture, src_rect, dst->m_texture, GSVector4(scaled_sx, scaled_sy, scaled_sx + scaled_w, scaled_sy + scaled_h), shader, false);
}
else
{
@ -5725,8 +5725,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
const bool outside_target = ((x + w) > dst->m_texture->GetWidth() || (y + h) > dst->m_texture->GetHeight());
GSTexture* sTex = dst->m_texture;
GSTexture* dTex = outside_target ?
g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color, true, PreferReusedLabelledTexture()) :
g_gs_device->CreateTexture(w, h, tlevels, GSTexture::Format::Color, PreferReusedLabelledTexture());
g_gs_device->CreateRenderTarget(w, h, GSTexture::Format::Color, true, PreferReusedLabelledTexture()) :
g_gs_device->CreateTexture(w, h, tlevels, GSTexture::Format::Color, PreferReusedLabelledTexture());
if (!dTex) [[unlikely]]
{
Console.Error("Failed to allocate %dx%d texture for offset source", w, h);
@ -6037,10 +6037,8 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// 'src' is the new texture cache entry (hence the output)
GSTexture* sTex = dst->m_texture;
GSTexture* dTex = use_texture ?
g_gs_device->CreateTexture(new_size.x, new_size.y, 1, GSTexture::Format::Color,
PreferReusedLabelledTexture()) :
g_gs_device->CreateRenderTarget(new_size.x, new_size.y, GSTexture::Format::Color,
source_rect_empty || destX != 0 || destY != 0, PreferReusedLabelledTexture());
g_gs_device->CreateTexture(new_size.x, new_size.y, 1, GSTexture::Format::Color, PreferReusedLabelledTexture()) :
g_gs_device->CreateRenderTarget(new_size.x, new_size.y, GSTexture::Format::Color, source_rect_empty || destX != 0 || destY != 0, PreferReusedLabelledTexture());
if (!dTex) [[unlikely]]
{
Console.Error("Failed to allocate %dx%d texture for target copy to source", new_size.x, new_size.y);
@ -6090,7 +6088,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con
// Adjust to match a PSMT8 texture (coordinates are double C32, we shouldn't be converting from anything else).
x_offset *= 2;
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 32)
if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 32)
y_offset *= 2;
src->m_region.SetX(x_offset, x_offset + tw);
@ -6552,7 +6550,7 @@ GSTextureCache::HashCacheEntry* GSTextureCache::LookupHashCache(const GIFRegTEX0
{
// don't bother hashing if we're not dumping or replacing.
const bool dump = GSConfig.DumpReplaceableTextures && (!FMVstarted || GSConfig.DumpTexturesWithFMVActive) &&
(clut ? GSConfig.DumpPaletteTextures : GSConfig.DumpDirectTextures);
(clut ? GSConfig.DumpPaletteTextures : GSConfig.DumpDirectTextures);
const bool replace = GSConfig.LoadTextureReplacements && GSTextureReplacements::HasAnyReplacementTextures();
bool can_cache = (TEX0.PSM >= PSMT8H && TEX0.PSM <= PSMT4HH) ? CanPreloadTextureSize(TEX0.TW, TEX0.TH) : CanCacheTextureSize(TEX0.TW, TEX0.TH);
if (!dump && !replace && !can_cache)
@ -6773,8 +6771,8 @@ GSTextureCache::Target* GSTextureCache::Target::Create(GIFRegTEX0 TEX0, int w, i
const int scaled_w = static_cast<int>(std::ceil(static_cast<float>(w) * scale));
const int scaled_h = static_cast<int>(std::ceil(static_cast<float>(h) * scale));
GSTexture* texture = (type == RenderTarget) ?
g_gs_device->CreateRenderTarget(scaled_w, scaled_h, GSTexture::Format::Color, clear, PreferReusedLabelledTexture()) :
g_gs_device->CreateDepthStencil(scaled_w, scaled_h, GSTexture::Format::DepthStencil, clear, PreferReusedLabelledTexture());
g_gs_device->CreateRenderTarget(scaled_w, scaled_h, GSTexture::Format::Color, clear, PreferReusedLabelledTexture()) :
g_gs_device->CreateDepthStencil(scaled_w, scaled_h, GSTexture::Format::DepthStencil, clear, PreferReusedLabelledTexture());
if (!texture)
return nullptr;
@ -7314,7 +7312,7 @@ void GSTextureCache::Source::Flush(u32 count, int layer, const GSOffset& off)
// need to offset if we're a region texture
const u8* src = s_unswizzle_buffer + (pitch * static_cast<u32>(std::max(tex_r.top - r.top, 0))) +
(static_cast<u32>(std::max(tex_r.left - r.left, 0)) << (m_palette ? 0 : 2));
(static_cast<u32>(std::max(tex_r.left - r.left, 0)) << (m_palette ? 0 : 2));
m_texture->Update(rint - tex_r.xyxy(), src, pitch, layer);
}
@ -7410,8 +7408,8 @@ GSTextureCache::Target::~Target()
if (src->m_from_target == this)
{
pxFail(fmt::format("Source at TBP {:x} for target at TBP {:x} on target invalidation",
static_cast<u32>(src->m_TEX0.TBP0), static_cast<u32>(m_TEX0.TBP0))
.c_str());
static_cast<u32>(src->m_TEX0.TBP0), static_cast<u32>(m_TEX0.TBP0)
).c_str());
break;
}
}
@ -7749,10 +7747,8 @@ bool GSTextureCache::Target::ResizeTexture(int new_unscaled_width, int new_unsca
const bool clear = (new_size.x > size.x || new_size.y > size.y);
GSTexture* tex = m_texture->IsDepthStencil() ?
g_gs_device->CreateDepthStencil(new_size.x, new_size.y, m_texture->GetFormat(), clear,
PreferReusedLabelledTexture()) :
g_gs_device->CreateRenderTarget(new_size.x, new_size.y, m_texture->GetFormat(), clear,
PreferReusedLabelledTexture());
g_gs_device->CreateDepthStencil(new_size.x, new_size.y, m_texture->GetFormat(), clear, PreferReusedLabelledTexture()) :
g_gs_device->CreateRenderTarget(new_size.x, new_size.y, m_texture->GetFormat(), clear, PreferReusedLabelledTexture());
if (!tex)
{
Console.Error("(ResizeTexture) Failed to allocate %dx%d texture from %dx%d texture", size.x, size.y, new_size.x, new_size.y);
@ -8261,8 +8257,8 @@ u64 GSTextureCache::PaletteKeyHash::operator()(const PaletteKey& key) const
{
pxAssert(key.pal == 16 || key.pal == 256);
return key.pal == 16 ?
GSXXH3_64bits(key.clut, sizeof(key.clut[0]) * 16) :
GSXXH3_64bits(key.clut, sizeof(key.clut[0]) * 256);
GSXXH3_64bits(key.clut, sizeof(key.clut[0]) * 16) :
GSXXH3_64bits(key.clut, sizeof(key.clut[0]) * 256);
};
// GSTextureCache::PaletteKeyEqual
@ -8571,7 +8567,7 @@ static void HashTextureLevel(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, GST
// Hash the expanded texture.
u8* ptr = temp + (pitch * static_cast<u32>(rect.top - block_rect.top)) +
static_cast<u32>(rect.left - block_rect.left);
static_cast<u32>(rect.left - block_rect.left);
if (pitch == row_size)
{
BlockHashAccumulate(hash_st, ptr, pitch * static_cast<u32>(th));
@ -8649,7 +8645,7 @@ void GSTextureCache::PreloadTexture(const GIFRegTEX0& TEX0, const GIFRegTEXA& TE
rtx(mem, off, block_rect, buff, pitch, TEXA);
const u8* ptr = buff + (pitch * static_cast<u32>(rect.top - block_rect.top)) +
(static_cast<u32>(rect.left - block_rect.left) << (paltex ? 0 : 2));
(static_cast<u32>(rect.left - block_rect.left) << (paltex ? 0 : 2));
if (alpha_minmax)
*alpha_minmax = GSGetRGBA8AlphaMinMax(ptr, unoffset_rect.width(), unoffset_rect.height(), pitch);

View File

@ -290,7 +290,7 @@ public:
public:
HashCacheEntry* m_from_hash_cache = nullptr;
std::shared_ptr<Palette> m_palette_obj;
std::unique_ptr<u32[]> m_valid;// each u32 bits map to the 32 blocks of that page
std::unique_ptr<u32[]> m_valid; // each u32 bits map to the 32 blocks of that page
GSTexture* m_palette = nullptr;
GSVector4i m_valid_rect = {};
GSVector2i m_lod = {};
@ -398,13 +398,13 @@ public:
struct SurfaceOffsetKey
{
std::array<SurfaceOffsetKeyElem, 2> elems; // A and B elems.
std::array<SurfaceOffsetKeyElem, 2> elems; // A and B elems.
};
struct SurfaceOffset
{
bool is_valid;
GSVector4i b2a_offset; // B to A offset in B coords.
GSVector4i b2a_offset; // B to A offset in B coords.
};
struct SurfaceOffsetKeyHash
@ -504,9 +504,9 @@ public:
Target* FindTargetOverlap(Target* target, int type, int psm);
void CombineAlignedInsideTargets(Target* target, GSTextureCache::Source* src = nullptr);
Target* LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false, bool preserve_scale = false, GSTextureCache::Source* src = nullptr, GSTextureCache::Target* ds = nullptr, int offset = -1);
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size,float scale, int type, bool used = true, u32 fbmask = 0,
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size, float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
const GSVector4i draw_rc = GSVector4i::zero(), GSTextureCache::Source* src = nullptr);
Target* LookupDisplayTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, bool is_feedback);

View File

@ -380,10 +380,8 @@ constexpr DDS_PIXELFORMAT DDSPF_R8G8B8 = {
static bool DDSPixelFormatMatches(const DDS_PIXELFORMAT& pf1, const DDS_PIXELFORMAT& pf2)
{
return std::tie(pf1.dwSize, pf1.dwFlags, pf1.dwFourCC, pf1.dwRGBBitCount, pf1.dwRBitMask,
pf1.dwGBitMask, pf1.dwGBitMask, pf1.dwBBitMask, pf1.dwABitMask) ==
std::tie(pf2.dwSize, pf2.dwFlags, pf2.dwFourCC, pf2.dwRGBBitCount, pf2.dwRBitMask,
pf2.dwGBitMask, pf2.dwGBitMask, pf2.dwBBitMask, pf2.dwABitMask);
return std::tie(pf1.dwSize, pf1.dwFlags, pf1.dwFourCC, pf1.dwRGBBitCount, pf1.dwRBitMask, pf1.dwGBitMask, pf1.dwGBitMask, pf1.dwBBitMask, pf1.dwABitMask) ==
std::tie(pf2.dwSize, pf2.dwFlags, pf2.dwFourCC, pf2.dwRGBBitCount, pf2.dwRBitMask, pf2.dwGBitMask, pf2.dwGBitMask, pf2.dwBBitMask, pf2.dwABitMask);
}
struct DDSLoadInfo

View File

@ -363,7 +363,7 @@ std::unique_ptr<GSDownloadTextureOGL> GSDownloadTextureOGL::Create(u32 width, u3
const u32 buffer_size = GetBufferSize(width, height, format, TEXTURE_UPLOAD_PITCH_ALIGNMENT);
const bool use_buffer_storage = (GLAD_GL_VERSION_4_4 || GLAD_GL_ARB_buffer_storage || GLAD_GL_EXT_buffer_storage) &&
!GSDeviceOGL::GetInstance()->IsDownloadPBODisabled();
!GSDeviceOGL::GetInstance()->IsDownloadPBODisabled();
if (use_buffer_storage)
{
GLuint buffer_id;

View File

@ -658,8 +658,8 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
vkGetDeviceQueue(m_device, m_present_queue_family_index, 0, &m_present_queue);
}
m_spinning_supported = m_spin_queue_family_index != queue_family_count &&
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 &&
m_device_properties.limits.timestampPeriod > 0;
queue_family_properties[m_graphics_queue_family_index].timestampValidBits > 0 &&
m_device_properties.limits.timestampPeriod > 0;
m_spin_queue_is_graphics_queue =
m_spin_queue_family_index == m_graphics_queue_family_index && spin_queue_index == 0;
@ -1089,7 +1089,7 @@ bool GSDeviceVK::SetGPUTimingEnabled(bool enabled)
void GSDeviceVK::ScanForCommandBufferCompletion()
{
for (u32 check_index = (m_current_frame + 1) % NUM_COMMAND_BUFFERS; check_index != m_current_frame;
check_index = (check_index + 1) % NUM_COMMAND_BUFFERS)
check_index = (check_index + 1) % NUM_COMMAND_BUFFERS)
{
FrameResources& resources = m_frame_resources[check_index];
if (resources.fence_counter <= m_completed_fence_counter)
@ -2719,8 +2719,8 @@ VkFormat GSDeviceVK::LookupNativeFormat(GSTexture::Format format) const
}};
return (format != GSTexture::Format::DepthStencil || m_features.stencil_buffer) ?
s_format_mapping[static_cast<int>(format)] :
VK_FORMAT_D32_SFLOAT;
s_format_mapping[static_cast<int>(format)] :
VK_FORMAT_D32_SFLOAT;
}
GSTexture* GSDeviceVK::CreateSurface(GSTexture::Type type, int width, int height, int levels, GSTexture::Format format)
@ -3197,12 +3197,10 @@ void GSDeviceVK::DoMerge(GSTexture* sTex[3], GSVector4* sRect, GSTexture* dTex,
EndRenderPass();
// transition everything before starting the new render pass
const bool has_input_0 =
(sTex[0] && (sTex[0]->GetState() == GSTexture::State::Dirty ||
(sTex[0]->GetState() == GSTexture::State::Cleared || sTex[0]->GetClearColor() != 0)));
const bool has_input_0 = (sTex[0] &&
(sTex[0]->GetState() == GSTexture::State::Dirty || (sTex[0]->GetState() == GSTexture::State::Cleared || sTex[0]->GetClearColor() != 0)));
const bool has_input_1 = (PMODE.SLBG == 0 || feedback_write_2_but_blend_bg) && sTex[1] &&
(sTex[1]->GetState() == GSTexture::State::Dirty ||
(sTex[1]->GetState() == GSTexture::State::Cleared || sTex[1]->GetClearColor() != 0));
(sTex[1]->GetState() == GSTexture::State::Dirty || (sTex[1]->GetState() == GSTexture::State::Cleared || sTex[1]->GetClearColor() != 0));
if (has_input_0)
{
static_cast<GSTextureVK*>(sTex[0])->CommitClear();
@ -3825,15 +3823,14 @@ bool GSDeviceVK::CreateRenderPasses()
{
for (u32 opa = VK_ATTACHMENT_LOAD_OP_LOAD; opa <= VK_ATTACHMENT_LOAD_OP_DONT_CARE; opa++)
{
for (u32 opb = VK_ATTACHMENT_LOAD_OP_LOAD; opb <= VK_ATTACHMENT_LOAD_OP_DONT_CARE;
opb++)
for (u32 opb = VK_ATTACHMENT_LOAD_OP_LOAD; opb <= VK_ATTACHMENT_LOAD_OP_DONT_CARE; opb++)
{
const VkFormat rp_rt_format =
(rt != 0) ? ((colclip != 0) ? colclip_rt_format : rt_format) : VK_FORMAT_UNDEFINED;
const VkFormat rp_depth_format = (ds != 0) ? depth_format : VK_FORMAT_UNDEFINED;
const VkAttachmentLoadOp opc = (!stencil || !m_features.stencil_buffer) ?
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
VK_ATTACHMENT_LOAD_OP_LOAD;
VK_ATTACHMENT_LOAD_OP_DONT_CARE :
VK_ATTACHMENT_LOAD_OP_LOAD;
GET(m_tfx_render_pass[rt][ds][colclip][stencil][fbl][dsp][opa][opb], rp_rt_format,
rp_depth_format, (fbl != 0), (dsp != 0), static_cast<VkAttachmentLoadOp>(opa),
static_cast<VkAttachmentLoadOp>(opb), static_cast<VkAttachmentLoadOp>(opc));
@ -3896,8 +3893,7 @@ bool GSDeviceVK::CompileConvertPipelines()
gpb.SetNoBlendingState();
gpb.SetVertexShader(vs);
for (ShaderConvert i = ShaderConvert::COPY; static_cast<int>(i) < static_cast<int>(ShaderConvert::Count);
i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
for (ShaderConvert i = ShaderConvert::COPY; i < ShaderConvert::Count; i = static_cast<ShaderConvert>(static_cast<int>(i) + 1))
{
const bool depth = HasDepthOutput(i);
const int index = static_cast<int>(i);
@ -4108,8 +4104,7 @@ bool GSDeviceVK::CompilePresentPipelines()
gpb.SetNoStencilState();
gpb.SetRenderPass(m_swap_chain_render_pass, 0);
for (PresentShader i = PresentShader::COPY; static_cast<int>(i) < static_cast<int>(PresentShader::Count);
i = static_cast<PresentShader>(static_cast<int>(i) + 1))
for (PresentShader i = PresentShader::COPY; i < PresentShader::Count; i = static_cast<PresentShader>(static_cast<int>(i) + 1))
{
const int index = static_cast<int>(i);
@ -5610,7 +5605,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
// If we have a colclip in progress, we need to use the colclip texture, but we can't check this later as there's a chicken/egg problem with the pipe setup.
GSTexture* backup_rt = config.rt;
if(colclip_rt)
if (colclip_rt)
config.rt = colclip_rt;
date_image = SetupPrimitiveTrackingDATE(config);
@ -5838,8 +5833,9 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
// Only draw to the active area of the colclip hw target. Except when depth is cleared, we need to use the full
// buffer size, otherwise it'll only clear the draw part of the depth buffer.
const GSVector4i render_area = (pipe.ps.colclip_hw && (config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertAndResolve) && ds_op != VK_ATTACHMENT_LOAD_OP_CLEAR) ? config.drawarea :
GSVector4i::loadh(rtsize);
const GSVector4i render_area = (pipe.ps.colclip_hw && (config.colclip_mode == GSHWDrawConfig::ColClipMode::ConvertAndResolve) && ds_op != VK_ATTACHMENT_LOAD_OP_CLEAR)
? config.drawarea
: GSVector4i::loadh(rtsize);
if (is_clearing_rt)
{
@ -6053,7 +6049,7 @@ VkImageMemoryBarrier GSDeviceVK::GetColorBufferBarrier(GSTextureVK* rt) const
VkDependencyFlags GSDeviceVK::GetColorBufferBarrierFlags() const
{
return UseFeedbackLoopLayout() ? (VK_DEPENDENCY_BY_REGION_BIT | VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT) :
VK_DEPENDENCY_BY_REGION_BIT;
VK_DEPENDENCY_BY_REGION_BIT;
}
void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt,

View File

@ -640,10 +640,10 @@ private:
DIRTY_FLAG_TFX_TEXTURE_PRIMID = (DIRTY_FLAG_TFX_TEXTURE_0 << 3),
DIRTY_FLAG_TFX_TEXTURES = DIRTY_FLAG_TFX_TEXTURE_TEX | DIRTY_FLAG_TFX_TEXTURE_PALETTE |
DIRTY_FLAG_TFX_TEXTURE_RT | DIRTY_FLAG_TFX_TEXTURE_PRIMID,
DIRTY_FLAG_TFX_TEXTURE_RT | DIRTY_FLAG_TFX_TEXTURE_PRIMID,
DIRTY_BASE_STATE = DIRTY_FLAG_INDEX_BUFFER | DIRTY_FLAG_PIPELINE | DIRTY_FLAG_VIEWPORT | DIRTY_FLAG_SCISSOR |
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_LINE_WIDTH,
DIRTY_FLAG_BLEND_CONSTANTS | DIRTY_FLAG_LINE_WIDTH,
DIRTY_TFX_STATE = DIRTY_BASE_STATE | DIRTY_FLAG_TFX_TEXTURES,
DIRTY_UTILITY_STATE = DIRTY_BASE_STATE | DIRTY_FLAG_UTILITY_TEXTURE,
DIRTY_CONSTANT_BUFFER_STATE = DIRTY_FLAG_VS_CONSTANT_BUFFER | DIRTY_FLAG_PS_CONSTANT_BUFFER,

View File

@ -33,14 +33,14 @@ static VkImageLayout GetVkImageLayout(GSTextureVK::Layout layout)
VK_IMAGE_LAYOUT_GENERAL, // General
}};
return (layout == GSTextureVK::Layout::FeedbackLoop && GSDeviceVK::GetInstance()->UseFeedbackLoopLayout()) ?
VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT :
s_vk_layout_mapping[static_cast<u32>(layout)];
VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT :
s_vk_layout_mapping[static_cast<u32>(layout)];
}
static VkAccessFlagBits GetFeedbackLoopInputAccessBits()
{
return GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_ACCESS_SHADER_READ_BIT :
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
}
GSTextureVK::GSTextureVK(Type type, Format format, int width, int height, int levels, VkImage image,
@ -102,8 +102,8 @@ std::unique_ptr<GSTextureVK> GSTextureVK::Create(Type type, Format format, int w
ici.usage =
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
(GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT :
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
(GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
: VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
}
break;
@ -113,8 +113,8 @@ std::unique_ptr<GSTextureVK> GSTextureVK::Create(Type type, Format format, int w
ici.usage =
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
(GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT :
0);
(GSDeviceVK::GetInstance()->UseFeedbackLoopLayout() ? VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT
: 0);
vci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
break;
@ -123,7 +123,7 @@ std::unique_ptr<GSTextureVK> GSTextureVK::Create(Type type, Format format, int w
{
pxAssert(levels == 1);
ici.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT;
VK_IMAGE_USAGE_SAMPLED_BIT;
}
break;
@ -202,8 +202,7 @@ void GSTextureVK::Destroy(bool defer)
{
if (other_tex)
{
for (auto other_it = other_tex->m_framebuffers.begin(); other_it != other_tex->m_framebuffers.end();
++other_it)
for (auto other_it = other_tex->m_framebuffers.begin(); other_it != other_tex->m_framebuffers.end(); ++other_it)
{
if (std::get<0>(*other_it) == this)
{
@ -566,7 +565,7 @@ void GSTextureVK::TransitionSubresourcesToLayout(
if (m_type == Type::DepthStencil)
{
aspect = g_gs_device->Features().stencil_buffer ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) :
VK_IMAGE_ASPECT_DEPTH_BIT;
VK_IMAGE_ASPECT_DEPTH_BIT;
}
else
{
@ -638,15 +637,12 @@ void GSTextureVK::TransitionSubresourcesToLayout(
break;
case Layout::FeedbackLoop:
barrier.srcAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ?
(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
GetFeedbackLoopInputAccessBits()) :
(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT);
srcStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ?
(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) :
(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
barrier.srcAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT)
? (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | GetFeedbackLoopInputAccessBits())
: (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT);
srcStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT)
? (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
: (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
break;
case Layout::ReadWriteImage:
@ -714,15 +710,12 @@ void GSTextureVK::TransitionSubresourcesToLayout(
break;
case Layout::FeedbackLoop:
barrier.dstAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ?
(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
GetFeedbackLoopInputAccessBits()) :
(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT);
dstStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT) ?
(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) :
(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
barrier.dstAccessMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT)
? (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | GetFeedbackLoopInputAccessBits())
: (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT);
dstStageMask = (aspect == VK_IMAGE_ASPECT_COLOR_BIT)
? (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT)
: (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
break;
case Layout::ReadWriteImage:
@ -946,4 +939,4 @@ void GSDownloadTextureVK::SetDebugName(std::string_view name)
Vulkan::SetObjectName(GSDeviceVK::GetInstance()->GetDevice(), m_buffer, "%.*s", static_cast<int>(name.size()), name.data());
}
#endif
#endif

View File

@ -114,14 +114,14 @@ namespace Vulkan
void AddBlendAttachment(bool blend_enable, VkBlendFactor src_factor, VkBlendFactor dst_factor, VkBlendOp op,
VkBlendFactor alpha_src_factor, VkBlendFactor alpha_dst_factor, VkBlendOp alpha_op,
VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
void SetBlendAttachment(u32 attachment, bool blend_enable, VkBlendFactor src_factor, VkBlendFactor dst_factor,
VkBlendOp op, VkBlendFactor alpha_src_factor, VkBlendFactor alpha_dst_factor, VkBlendOp alpha_op,
VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
void SetColorWriteMask(
u32 attachment, VkColorComponentFlags write_mask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
void AddBlendFlags(u32 flags);
void ClearBlendAttachments();
@ -407,4 +407,4 @@ namespace Vulkan
va_end(ap);
#endif
}
} // namespace Vulkan
} // namespace Vulkan