mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-07-21 22:44:10 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f8c98dccf | ||
|
|
59e422c538 | ||
|
|
5ef5e41e69 | ||
|
|
58facc8ab1 | ||
|
|
3341514bb4 | ||
|
|
0434aba3a8 | ||
|
|
c1cb214a03 | ||
|
|
3233a3cf8f | ||
|
|
469a3d60b2 | ||
|
|
bb35bed104 | ||
|
|
624acf5533 | ||
|
|
f71f0b9cb0 |
@@ -56,6 +56,11 @@ bool HTTPDownloaderWinHttp::Initialize(std::string user_agent)
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD timeout_ms = 15000;
|
||||
WinHttpSetOption(m_hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &timeout_ms, sizeof(timeout_ms));
|
||||
WinHttpSetOption(m_hSession, WINHTTP_OPTION_SEND_TIMEOUT, &timeout_ms, sizeof(timeout_ms));
|
||||
WinHttpSetOption(m_hSession, WINHTTP_OPTION_RECEIVE_TIMEOUT, &timeout_ms, sizeof(timeout_ms));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -290,10 +295,13 @@ bool HTTPDownloaderWinHttp::StartRequest(HTTPDownloader::Request* request)
|
||||
req->status_code = HTTP_STATUS_ERROR;
|
||||
req->state.store(Request::State::Complete);
|
||||
}
|
||||
else
|
||||
{
|
||||
DevCon.WriteLn("Started HTTP request for '%s'", req->url.c_str());
|
||||
req->state = Request::State::Started;
|
||||
req->start_time = Common::Timer::GetCurrentValue();
|
||||
}
|
||||
|
||||
DevCon.WriteLn("Started HTTP request for '%s'", req->url.c_str());
|
||||
req->state = Request::State::Started;
|
||||
req->start_time = Common::Timer::GetCurrentValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -90,17 +90,15 @@ AchievementSettingsWidget::AchievementSettingsWidget(SettingsWindow* settings_di
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove login and game info, not relevant for per-game
|
||||
// hide login and game info, not relevant for per-game
|
||||
m_ui.verticalLayout->removeWidget(m_ui.gameInfoBox);
|
||||
m_ui.gameInfoBox->deleteLater();
|
||||
m_ui.gameInfoBox = nullptr;
|
||||
m_ui.gameInfoBox->hide();
|
||||
m_ui.verticalLayout->removeWidget(m_ui.loginBox);
|
||||
m_ui.loginBox->deleteLater();
|
||||
m_ui.loginBox = nullptr;
|
||||
m_ui.loginBox->hide();
|
||||
|
||||
// sound effects
|
||||
m_ui.verticalLayout->removeWidget(m_ui.soundEffectsBox);
|
||||
m_ui.soundEffectsBox->deleteLater();
|
||||
m_ui.soundEffectsBox->hide();
|
||||
m_ui.soundEffectsBox = nullptr;
|
||||
}
|
||||
|
||||
@@ -121,9 +119,6 @@ void AchievementSettingsWidget::updateEnableState()
|
||||
const bool unlock = enabled && sound && dialog()->getEffectiveBoolValue("Achievements", "UnlockSound", true);
|
||||
const bool lbsound = enabled && sound && dialog()->getEffectiveBoolValue("Achievements", "LBSubmitSound", true);
|
||||
|
||||
m_ui.viewProfile->setEnabled(enabled);
|
||||
m_ui.loginButton->setEnabled(enabled);
|
||||
|
||||
m_ui.hardcoreMode->setEnabled(enabled);
|
||||
m_ui.achievementNotifications->setEnabled(enabled);
|
||||
m_ui.leaderboardNotifications->setEnabled(enabled);
|
||||
|
||||
@@ -11,6 +11,28 @@
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="rcheevosDisclaimer">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p align="justify">PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at <a href="https://retroachievements.org/">retroachievements.org</a>.</p><p align="justify">To view the achievement list in-game, press the hotkey for <span style=" font-weight:600;">Open Pause Menu</span> and select <span style=" font-weight:600;">Achievements</span> from the menu.</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>enable</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="loginBox">
|
||||
<property name="title">
|
||||
@@ -18,32 +40,21 @@
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="acccountLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="enable">
|
||||
<property name="text">
|
||||
<string>Enable Achievements</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="loginStatus">
|
||||
<property name="text">
|
||||
<string>Username:
|
||||
<widget class="QLabel" name="loginStatus">
|
||||
<property name="text">
|
||||
<string>Username:
|
||||
Login token generated at:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>viewProfile</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>viewProfile</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="achievementButtons">
|
||||
@@ -94,62 +105,47 @@ Login token generated at:</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="rcheevosDisclaimer">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p align="justify">PCSX2 uses RetroAchievements as an achievement database and for tracking progress. To use achievements, please sign up for an account at <a href="https://retroachievements.org/">retroachievements.org</a>.</p><p align="justify">To view the achievement list in-game, press the hotkey for <span style=" font-weight:600;">Open Pause Menu</span> and select <span style=" font-weight:600;">Achievements</span> from the menu.</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::TextFormat::RichText</enum>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>enable</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="settingsBox">
|
||||
<property name="title">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="unofficialAchievements">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="enable">
|
||||
<property name="text">
|
||||
<string>Test Unofficial Achievements</string>
|
||||
<string>Enable Achievements</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="spectatorMode">
|
||||
<property name="text">
|
||||
<string>Enable Spectator Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="hardcoreMode">
|
||||
<property name="text">
|
||||
<string>Enable Hardcore Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="spectatorMode">
|
||||
<property name="text">
|
||||
<string>Enable Spectator Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="encoreMode">
|
||||
<property name="text">
|
||||
<string>Enable Encore Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="unofficialAchievements">
|
||||
<property name="text">
|
||||
<string>Test Unofficial Achievements</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -537,9 +533,9 @@ Login token generated at:</string>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>enable</tabstop>
|
||||
<tabstop>viewProfile</tabstop>
|
||||
<tabstop>loginButton</tabstop>
|
||||
<tabstop>enable</tabstop>
|
||||
<tabstop>hardcoreMode</tabstop>
|
||||
<tabstop>spectatorMode</tabstop>
|
||||
<tabstop>encoreMode</tabstop>
|
||||
|
||||
@@ -321,6 +321,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="useDebugBlend">
|
||||
<property name="text">
|
||||
<string>Use Debug Blend</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -355,6 +362,7 @@
|
||||
<tabstop>palFrameRate</tabstop>
|
||||
<tabstop>overrideTextureBarriers</tabstop>
|
||||
<tabstop>useDebugDevice</tabstop>
|
||||
<tabstop>useDebugBlend</tabstop>
|
||||
<tabstop>disableFramebufferFetch</tabstop>
|
||||
<tabstop>disableShaderCache</tabstop>
|
||||
<tabstop>disableVertexShaderExpand</tabstop>
|
||||
|
||||
@@ -225,6 +225,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_advanced.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_advanced.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_advanced.useDebugBlend, "EmuCore/GS", "UseDebugBlend", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_advanced.disableMailboxPresentation, "EmuCore/GS", "DisableMailboxPresentation", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_advanced.extendedUpscales, "EmuCore/GS", "ExtendedUpscalingMultipliers", false);
|
||||
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_advanced.exclusiveFullscreenControl, "EmuCore/GS", "ExclusiveFullscreenControl", -1, -1);
|
||||
@@ -766,6 +767,9 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsWindow* settings_dialog,
|
||||
dialog()->registerWidgetHelp(m_advanced.useDebugDevice, tr("Enable Debug Device"), tr("Unchecked"),
|
||||
tr("Enables API-level validation of graphics commands."));
|
||||
|
||||
dialog()->registerWidgetHelp(m_advanced.useDebugBlend, tr("Enable Debug Blend"), tr("Unchecked"),
|
||||
tr("Forces SW blending and disables several optimizations."));
|
||||
|
||||
dialog()->registerWidgetHelp(m_advanced.gsDownloadMode, tr("GS Download Mode"), tr("Accurate"),
|
||||
tr("Skips synchronizing with the GS thread and host GPU for GS downloads. "
|
||||
"Can result in a large speed boost on slower systems, at the cost of many broken graphical effects. "
|
||||
|
||||
+1457
-1426
File diff suppressed because it is too large
Load Diff
+11
-4
@@ -745,11 +745,18 @@ void Achievements::ClientServerCall(
|
||||
{
|
||||
HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, const std::string& content_type, HTTPDownloader::Request::Data data)
|
||||
{
|
||||
const bool is_error = (status_code <= 0);
|
||||
const bool is_retryable =
|
||||
is_error && (status_code == HTTPDownloader::HTTP_STATUS_TIMEOUT);
|
||||
|
||||
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;
|
||||
rr.http_status_code =
|
||||
is_error
|
||||
? (is_retryable
|
||||
? RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR
|
||||
: RC_API_SERVER_RESPONSE_CLIENT_ERROR)
|
||||
: status_code;
|
||||
|
||||
rr.body_length = data.size();
|
||||
rr.body = reinterpret_cast<const char*>(data.data());
|
||||
|
||||
|
||||
+2
-1
@@ -760,6 +760,7 @@ struct Pcsx2Config
|
||||
PCRTCOverscan : 1,
|
||||
IntegerScaling : 1,
|
||||
UseDebugDevice : 1,
|
||||
UseDebugBlend : 1,
|
||||
UseBlitSwapChain : 1,
|
||||
DisableShaderCache : 1,
|
||||
DisableFramebufferFetch : 1,
|
||||
@@ -791,7 +792,7 @@ struct Pcsx2Config
|
||||
PreloadFrameWithGSData : 1,
|
||||
Mipmap : 1,
|
||||
HWMipmap : 1,
|
||||
HWAccurateAlphaTest: 1,
|
||||
HWAccurateAlphaTest : 1,
|
||||
HWAA1 : 1,
|
||||
ManualUserHacks : 1,
|
||||
UserHacks_AlignSpriteX : 1,
|
||||
|
||||
+34
-23
@@ -118,30 +118,12 @@ bool PCAPAdapter::recv(NetPacket* pkt)
|
||||
if (!blocking && NetAdapter::recv(pkt))
|
||||
return true;
|
||||
|
||||
pcap_pkthdr* header;
|
||||
const u_char* pkt_data;
|
||||
|
||||
// pcap bridged will pick up packets not intended for us, returning false on those packets will incur a 1ms wait.
|
||||
// This delays getting packets we need, so instead loop untill a valid packet, or no packet, is returned from pcap_next_ex.
|
||||
while (pcap_next_ex(hpcap, &header, &pkt_data) > 0)
|
||||
while (RecvPCAPPacket(pkt))
|
||||
{
|
||||
// 1518 is the largest Ethernet frame we can get using an MTU of 1500 (assuming no VLAN tagging).
|
||||
// This includes the FCS, which should be trimmed (PS2 SDK dosn't allow extra space for this).
|
||||
if (header->len > 1518)
|
||||
{
|
||||
Console.Error("DEV9: Dropped jumbo frame of size: %u", header->len);
|
||||
continue;
|
||||
}
|
||||
|
||||
pxAssert(header->len == header->caplen);
|
||||
|
||||
memcpy(pkt->buffer, pkt_data, header->len);
|
||||
pkt->size = static_cast<int>(header->len);
|
||||
|
||||
if (!switched)
|
||||
SetMACBridgedRecv(pkt);
|
||||
|
||||
if (VerifyPkt(pkt, header->len))
|
||||
if (VerifyPkt(pkt, pkt->size))
|
||||
{
|
||||
HandleFrameCheckSequence(pkt);
|
||||
|
||||
@@ -173,10 +155,39 @@ bool PCAPAdapter::send(NetPacket* pkt)
|
||||
if (!switched)
|
||||
SetMACBridgedSend(pkt);
|
||||
|
||||
if (pcap_sendpacket(hpcap, (u_char*)pkt->buffer, pkt->size))
|
||||
return false;
|
||||
else
|
||||
return SendPCAPPacket(pkt);
|
||||
}
|
||||
|
||||
bool PCAPAdapter::RecvPCAPPacket(NetPacket* pkt)
|
||||
{
|
||||
pcap_pkthdr* header;
|
||||
const u_char* pkt_data;
|
||||
|
||||
// pcap bridged will pick up packets not intended for us, returning false on those packets will incur a 1ms wait.
|
||||
// This delays getting packets we need, so instead loop untill a valid packet, or no packet, is returned from pcap_next_ex.
|
||||
while (pcap_next_ex(hpcap, &header, &pkt_data) > 0)
|
||||
{
|
||||
// 1518 is the largest Ethernet frame we can get using an MTU of 1500 (assuming no VLAN tagging).
|
||||
// This includes the FCS, which should be trimmed (PS2 SDK dosn't allow extra space for this).
|
||||
if (header->len > 1518)
|
||||
{
|
||||
Console.Error("DEV9: Dropped jumbo frame of size: %u", header->len);
|
||||
continue;
|
||||
}
|
||||
|
||||
pxAssert(header->len == header->caplen);
|
||||
|
||||
memcpy(pkt->buffer, pkt_data, header->len);
|
||||
pkt->size = static_cast<int>(header->len);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PCAPAdapter::SendPCAPPacket(const NetPacket* pkt)
|
||||
{
|
||||
return pcap_sendpacket(hpcap, reinterpret_cast<const u_char*>(pkt->buffer), pkt->size) == 0;
|
||||
}
|
||||
|
||||
void PCAPAdapter::reloadSettings()
|
||||
|
||||
@@ -39,6 +39,9 @@ private:
|
||||
bool InitPCAP(const std::string& adapter, bool promiscuous);
|
||||
bool SetMACSwitchedFilter(PacketReader::MAC_Address mac);
|
||||
|
||||
bool RecvPCAPPacket(NetPacket* pkt);
|
||||
bool SendPCAPPacket(const NetPacket* pkt);
|
||||
|
||||
void SetMACBridgedRecv(NetPacket* pkt);
|
||||
void SetMACBridgedSend(NetPacket* pkt);
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
namespace GSShaderCompileIndicator
|
||||
{
|
||||
inline constexpr std::uint64_t OSD_RECENT_COMPILE_NS = 500'000'000ULL;
|
||||
|
||||
inline std::atomic<std::uint32_t> s_active_compilations{0};
|
||||
inline std::atomic<std::uint64_t> s_last_compile_activity_ns{0};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
inline std::uint64_t steady_now_ns()
|
||||
{
|
||||
return static_cast<std::uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count());
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
inline void TouchCompileActivity()
|
||||
{
|
||||
s_last_compile_activity_ns.store(detail::steady_now_ns(), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
inline void BeginCompilation()
|
||||
{
|
||||
TouchCompileActivity();
|
||||
s_active_compilations.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
inline void EndCompilation()
|
||||
{
|
||||
s_active_compilations.fetch_sub(1, std::memory_order_relaxed);
|
||||
TouchCompileActivity();
|
||||
}
|
||||
|
||||
inline std::uint32_t GetActiveCompilationCount()
|
||||
{
|
||||
return s_active_compilations.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
inline bool ShouldShowOnOSD(std::uint64_t hold_ns = OSD_RECENT_COMPILE_NS)
|
||||
{
|
||||
if (GetActiveCompilationCount() != 0)
|
||||
return true;
|
||||
|
||||
const std::uint64_t last = s_last_compile_activity_ns.load(std::memory_order_relaxed);
|
||||
if (last == 0)
|
||||
return false;
|
||||
|
||||
const std::uint64_t now = detail::steady_now_ns();
|
||||
return now > last && (now - last) < hold_ns;
|
||||
}
|
||||
|
||||
inline float GetPostCompileFadeAlpha(std::uint64_t hold_ns = OSD_RECENT_COMPILE_NS)
|
||||
{
|
||||
if (GetActiveCompilationCount() != 0)
|
||||
return 1.0f;
|
||||
|
||||
const std::uint64_t last = s_last_compile_activity_ns.load(std::memory_order_relaxed);
|
||||
if (last == 0)
|
||||
return 0.0f;
|
||||
|
||||
const std::uint64_t now = detail::steady_now_ns();
|
||||
if (now <= last)
|
||||
return 1.0f;
|
||||
|
||||
const std::uint64_t elapsed = now - last;
|
||||
if (elapsed >= hold_ns)
|
||||
return 0.0f;
|
||||
|
||||
return 1.0f - static_cast<float>(elapsed) / static_cast<float>(hold_ns);
|
||||
}
|
||||
|
||||
struct ScopedCompilation
|
||||
{
|
||||
ScopedCompilation() { BeginCompilation(); }
|
||||
~ScopedCompilation() { EndCompilation(); }
|
||||
ScopedCompilation(const ScopedCompilation&) = delete;
|
||||
ScopedCompilation& operator=(const ScopedCompilation&) = delete;
|
||||
};
|
||||
} // namespace GSShaderCompileIndicator
|
||||
@@ -4642,13 +4642,13 @@ GSState::PRIM_OVERLAP GSState::GetPrimitiveOverlapDrawlistImpl(bool save_drawlis
|
||||
};
|
||||
|
||||
// First check: see if the triangles are part of a triangle strip.
|
||||
if (!got_bbox && !using_aa1)
|
||||
if (!got_bbox && !using_aa1 && !GSConfig.UseDebugBlend)
|
||||
{
|
||||
got_bbox = CheckTriangleStrips(j, skip, bbox, saved_tristrip);
|
||||
}
|
||||
|
||||
// Second check: see if the triangles are part of triangle fan.
|
||||
if (!got_bbox && !using_aa1)
|
||||
if (!got_bbox && !using_aa1 && !GSConfig.UseDebugBlend)
|
||||
{
|
||||
got_bbox = CheckTriangleQuads.template operator()<1>(j, skip, bbox);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "Config.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
#include "GS/Renderers/DX11/D3D.h"
|
||||
#include "GS/GSExtra.h"
|
||||
@@ -487,6 +488,8 @@ wil::com_ptr_nothrow<ID3DBlob> D3D::CompileShader(D3D::ShaderType type, D3D::Sha
|
||||
const std::string_view code, const D3D_SHADER_MACRO* macros /* = nullptr */,
|
||||
const char* entry_point /* = "main" */)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
const char* target;
|
||||
switch (shader_model)
|
||||
{
|
||||
|
||||
@@ -2907,7 +2907,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
ID3D11DepthStencilView* read_only_dsv = nullptr;
|
||||
if (config.tex && config.tex == config.ds)
|
||||
{
|
||||
if (m_features.test_and_sample_depth && !config.depth.zwe && !config.ps.IsFeedbackLoopDepth())
|
||||
if (m_features.test_and_sample_depth && !config.depth.zwe && !config.ps.IsFeedbackLoopDepth() && !config.alpha_second_pass.ps.IsFeedbackLoopDepth())
|
||||
read_only_dsv = static_cast<GSTexture11*>(config.ds)->ReadOnlyDepthStencilView();
|
||||
else
|
||||
config.tex = nullptr;
|
||||
@@ -2955,7 +2955,7 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
||||
(rt_feedbackloop_pass1 || rt_feedbackloop_pass2))))
|
||||
{
|
||||
config.require_one_barrier |= (tex_is_fb && !config.require_full_barrier);
|
||||
config.alpha_second_pass.require_one_barrier |= (tex_is_fb && !config.require_full_barrier);
|
||||
config.alpha_second_pass.require_one_barrier |= (tex_is_fb && !config.alpha_second_pass.require_full_barrier);
|
||||
|
||||
// Requires a copy of the RT.
|
||||
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, draw_rt->GetFormat(), true);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "GS/Renderers/DX12/D3D12ShaderCache.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "ShaderCacheVersion.h"
|
||||
@@ -540,6 +541,8 @@ D3D12ShaderCache::ComPtr<ID3DBlob> D3D12ShaderCache::CompileAndAddShaderBlob(
|
||||
D3D12ShaderCache::ComPtr<ID3D12PipelineState> D3D12ShaderCache::CompileAndAddPipeline(
|
||||
ID3D12Device* device, const CacheIndexKey& key, const D3D12_GRAPHICS_PIPELINE_STATE_DESC& gpdesc)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
ComPtr<ID3D12PipelineState> pso;
|
||||
HRESULT hr = device->CreateGraphicsPipelineState(&gpdesc, IID_PPV_ARGS(pso.put()));
|
||||
if (FAILED(hr))
|
||||
@@ -555,6 +558,8 @@ D3D12ShaderCache::ComPtr<ID3D12PipelineState> D3D12ShaderCache::CompileAndAddPip
|
||||
D3D12ShaderCache::ComPtr<ID3D12PipelineState> D3D12ShaderCache::CompileAndAddPipeline(
|
||||
ID3D12Device* device, const CacheIndexKey& key, const D3D12_COMPUTE_PIPELINE_STATE_DESC& gpdesc)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
ComPtr<ID3D12PipelineState> pso;
|
||||
HRESULT hr = device->CreateComputePipelineState(&gpdesc, IID_PPV_ARGS(pso.put()));
|
||||
if (FAILED(hr))
|
||||
|
||||
@@ -6955,27 +6955,26 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, DATEOptio
|
||||
break;
|
||||
}
|
||||
|
||||
if (features.framebuffer_fetch)
|
||||
{
|
||||
const bool force_sw_blending =
|
||||
// If we have fbfetch, use software blending when we need the fb value for anything else.
|
||||
// This saves outputting the second color when it's not needed.
|
||||
if (one_barrier || m_conf.require_full_barrier)
|
||||
{
|
||||
sw_blending = true;
|
||||
color_dest_blend = false;
|
||||
accumulation_blend = false;
|
||||
blend_mix = false;
|
||||
}
|
||||
}
|
||||
(features.framebuffer_fetch && (one_barrier || m_conf.require_full_barrier)) ||
|
||||
|
||||
if (m_conf.ps.IsFeedbackLoopDepth() && !features.depth_feedback)
|
||||
{
|
||||
// If we are doing depth feedback with a second RT we must use SW blending to avoid
|
||||
// mixing dual source blending with multiple render targets.
|
||||
(m_conf.ps.IsFeedbackLoopDepth() && !features.depth_feedback) ||
|
||||
|
||||
// Force SW blending with barriers.
|
||||
GSConfig.UseDebugBlend;
|
||||
|
||||
if (force_sw_blending)
|
||||
{
|
||||
sw_blending = true;
|
||||
color_dest_blend = false;
|
||||
accumulation_blend = false;
|
||||
blend_mix = false;
|
||||
color_dest_blend2 = false;
|
||||
blend_zero_to_one_range = false;
|
||||
}
|
||||
|
||||
// Color clip
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "GS/Renderers/Metal/GSDeviceMTL.h"
|
||||
#include "GS/Renderers/Metal/GSTextureMTL.h"
|
||||
#include "GS/GSPerfMon.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/HostSys.h"
|
||||
@@ -712,6 +713,7 @@ MRCOwned<id<MTLFunction>> GSDeviceMTL::LoadShader(NSString* name)
|
||||
|
||||
MRCOwned<id<MTLRenderPipelineState>> GSDeviceMTL::MakePipeline(MTLRenderPipelineDescriptor* desc, id<MTLFunction> vertex, id<MTLFunction> fragment, NSString* name)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
[desc setLabel:name];
|
||||
[desc setVertexFunction:vertex];
|
||||
[desc setFragmentFunction:fragment];
|
||||
@@ -728,6 +730,7 @@ MRCOwned<id<MTLRenderPipelineState>> GSDeviceMTL::MakePipeline(MTLRenderPipeline
|
||||
|
||||
MRCOwned<id<MTLComputePipelineState>> GSDeviceMTL::MakeComputePipeline(id<MTLFunction> compute, NSString* name)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
MRCOwned<MTLComputePipelineDescriptor*> desc = MRCTransfer([MTLComputePipelineDescriptor new]);
|
||||
[desc setLabel:name];
|
||||
[desc setComputeFunction:compute];
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "GSMTLDeviceInfo.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/Path.h"
|
||||
|
||||
@@ -56,7 +57,10 @@ static bool detectPrimIDSupport(id<MTLDevice> dev, id<MTLLibrary> lib)
|
||||
[desc setFragmentFunction:MRCTransfer([lib newFunctionWithName:@"primid_test"])];
|
||||
[[desc colorAttachments][0] setPixelFormat:MTLPixelFormatR8Uint];
|
||||
NSError* err;
|
||||
[[dev newRenderPipelineStateWithDescriptor:desc error:&err] release];
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
[[dev newRenderPipelineStateWithDescriptor:desc error:&err] release];
|
||||
}
|
||||
return !err;
|
||||
}
|
||||
|
||||
@@ -88,7 +92,11 @@ static DetectionResult detectIntelGPU(id<MTLDevice> dev, id<MTLLibrary> lib)
|
||||
[pdesc setVertexFunction:MRCTransfer([lib newFunctionWithName:@"fs_triangle"])];
|
||||
[pdesc setFragmentFunction:MRCTransfer([lib newFunctionWithName:@"fbfetch_test"])];
|
||||
[[pdesc colorAttachments][0] setPixelFormat:MTLPixelFormatRGBA8Unorm];
|
||||
auto pipe = MRCTransfer([dev newRenderPipelineStateWithDescriptor:pdesc error:nil]);
|
||||
MRCOwned<id<MTLRenderPipelineState>> pipe;
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
pipe = MRCTransfer([dev newRenderPipelineStateWithDescriptor:pdesc error:nil]);
|
||||
}
|
||||
if (!pipe)
|
||||
return DetectionResult::HaswellOrNotIntel;
|
||||
auto buf = MRCTransfer([dev newBufferWithLength:4 options:MTLResourceStorageModeShared]);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "GS/Renderers/OpenGL/GLShaderCache.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "ShaderCacheVersion.h"
|
||||
@@ -366,6 +367,8 @@ bool GLShaderCache::WriteToBlobFile(const CacheIndexKey& key, const std::vector<
|
||||
std::optional<GLProgram> GLShaderCache::CompileProgram(const std::string_view vertex_shader,
|
||||
const std::string_view fragment_shader, const PreLinkCallback& callback, bool set_retrievable)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
GLProgram prog;
|
||||
if (!prog.Compile(vertex_shader, fragment_shader))
|
||||
return std::nullopt;
|
||||
@@ -385,6 +388,8 @@ std::optional<GLProgram> GLShaderCache::CompileProgram(const std::string_view ve
|
||||
std::optional<GLProgram> GLShaderCache::CompileComputeProgram(
|
||||
const std::string_view glsl, const PreLinkCallback& callback, bool set_retrievable)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
GLProgram prog;
|
||||
if (!prog.CompileCompute(glsl))
|
||||
return std::nullopt;
|
||||
|
||||
@@ -2821,7 +2821,19 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
|
||||
SetupPipeline(psel);
|
||||
|
||||
bool rt_hazard_barrier = config.tex && (config.tex == config.ds || config.tex == config.rt);
|
||||
bool rt_hazard_barrier = config.tex && config.tex == config.rt;
|
||||
if (config.tex && config.tex == config.ds)
|
||||
{
|
||||
if (m_features.test_and_sample_depth && !config.depth.zwe && !config.ps.IsFeedbackLoopDepth() && !config.alpha_second_pass.ps.IsFeedbackLoopDepth())
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
else if (m_features.texture_barrier)
|
||||
rt_hazard_barrier = true;
|
||||
else
|
||||
config.tex = nullptr;
|
||||
}
|
||||
|
||||
// In Time Crisis:
|
||||
// 1. Fullscreen sprite reads depth and writes alpha (rt_hazard_barrier true from config.ds == config.tex)
|
||||
// 2. Fullscreen sprite writes gray, rta hw blend blends based on dst alpha.
|
||||
@@ -2938,7 +2950,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
||||
(rt_feedbackloop_pass1 || rt_feedbackloop_pass2))))
|
||||
{
|
||||
config.require_one_barrier |= (tex_is_fb && !config.require_full_barrier);
|
||||
config.alpha_second_pass.require_one_barrier |= (tex_is_fb && !config.require_full_barrier);
|
||||
config.alpha_second_pass.require_one_barrier |= (tex_is_fb && !config.alpha_second_pass.require_full_barrier);
|
||||
|
||||
// Requires a copy of the RT.
|
||||
draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, 1, draw_rt->GetFormat(), true);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "BuildVersion.h"
|
||||
#include "Host.h"
|
||||
#include "ImGui/ImGuiManager.h"
|
||||
|
||||
#include "common/Console.h"
|
||||
#include "common/BitUtils.h"
|
||||
@@ -2353,6 +2354,7 @@ GSDevice::PresentResult GSDeviceVK::BeginPresent(bool frame_skip)
|
||||
if (res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR)
|
||||
{
|
||||
ResizeWindow(0, 0, m_window_info.surface_scale);
|
||||
ImGuiManager::WindowResized();
|
||||
res = m_swap_chain->AcquireNextImage();
|
||||
}
|
||||
else if (res == VK_ERROR_SURFACE_LOST_KHR)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "GS/Renderers/Vulkan/VKBuilders.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
@@ -279,6 +280,8 @@ void Vulkan::GraphicsPipelineBuilder::Clear()
|
||||
VkPipeline Vulkan::GraphicsPipelineBuilder::Create(
|
||||
VkDevice device, VkPipelineCache pipeline_cache, bool clear /* = true */)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkResult res = vkCreateGraphicsPipelines(device, pipeline_cache, 1, &m_ci, nullptr, &pipeline);
|
||||
if (res != VK_SUCCESS)
|
||||
@@ -588,6 +591,8 @@ void Vulkan::ComputePipelineBuilder::Clear()
|
||||
VkPipeline Vulkan::ComputePipelineBuilder::Create(
|
||||
VkDevice device, VkPipelineCache pipeline_cache /*= VK_NULL_HANDLE*/, bool clear /*= true*/)
|
||||
{
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
VkPipeline pipeline;
|
||||
VkResult res = vkCreateComputePipelines(device, pipeline_cache, 1, &m_ci, nullptr, &pipeline);
|
||||
if (res != VK_SUCCESS)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/Renderers/Vulkan/GSDeviceVK.h"
|
||||
#include "GS/Renderers/Vulkan/VKBuilders.h"
|
||||
@@ -230,6 +231,8 @@ std::optional<VKShaderCache::SPIRVCodeVector> VKShaderCache::CompileShaderToSPV(
|
||||
if (!dyn_shaderc::Open())
|
||||
return ret;
|
||||
|
||||
const GSShaderCompileIndicator::ScopedCompilation compiling;
|
||||
|
||||
shaderc_compile_options_t options = dyn_shaderc::shaderc_compile_options_initialize();
|
||||
pxAssertRel(options, "shaderc_compile_options_initialize() failed");
|
||||
|
||||
|
||||
@@ -4979,6 +4979,8 @@ void FullscreenUI::DrawAdvancedSettingsPage()
|
||||
MenuHeading(FSUI_CSTR("Graphics"));
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_BUG, "Use Debug Device"), FSUI_CSTR("Enables API-level validation of graphics commands."), "EmuCore/GS",
|
||||
"UseDebugDevice", false);
|
||||
|
||||
DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_BUG, "Use Debug Blend"), FSUI_CSTR("Forces SW blending and disables several optimizations."), "EmuCore/GS", "UseDebugBlend", false);
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
@@ -5446,6 +5448,7 @@ TRANSLATE_NOOP("FullscreenUI", "Sets the compression algorithm for savestate.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Sets the compression level for savestate.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Graphics");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Enables API-level validation of graphics commands.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Forces SW blending and disables several optimizations.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Settings");
|
||||
TRANSLATE_NOOP("FullscreenUI", "No cheats are available for this game.");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Cheat Codes");
|
||||
@@ -5997,6 +6000,7 @@ TRANSLATE_NOOP("FullscreenUI", "Enable IOP Recompiler");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Compression Method");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Compression Level");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Debug Device");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Debug Blend");
|
||||
TRANSLATE_NOOP("FullscreenUI", "FPU Multiply Hack");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Use Software Renderer For FMVs");
|
||||
TRANSLATE_NOOP("FullscreenUI", "Skip MPEG Hack");
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Config.h"
|
||||
#include "Counters.h"
|
||||
#include "GS/GS.h"
|
||||
#include "GS/GSShaderCompileIndicator.h"
|
||||
#include "GS/GSCapture.h"
|
||||
#include "GS/GSVector.h"
|
||||
#include "GS/Renderers/Common/GSDevice.h"
|
||||
@@ -143,6 +144,7 @@ namespace ImGuiManager
|
||||
{
|
||||
static void FormatProcessorStat(SmallStringBase& text, double usage, double time);
|
||||
static void DrawPerformanceOverlay(float& position_y, float scale, float margin, float spacing);
|
||||
static void DrawShaderCompileIndicator(float scale, float margin, float spacing);
|
||||
static void DrawSettingsOverlay(float scale, float margin, float spacing);
|
||||
static void DrawInputsOverlay(float scale, float margin, float spacing);
|
||||
static void DrawInputRecordingOverlay(float& position_y, float scale, float margin, float spacing);
|
||||
@@ -778,6 +780,72 @@ __ri void ImGuiManager::DrawPerformanceOverlay(float& position_y, float scale, f
|
||||
#undef DRAW_LINE
|
||||
}
|
||||
|
||||
__ri void ImGuiManager::DrawShaderCompileIndicator(float scale, float margin, float spacing)
|
||||
{
|
||||
static bool s_indicator_was_visible = false;
|
||||
static double s_indicator_fade_in_start = 0.0;
|
||||
|
||||
if (!GSConfig.OsdShowGPU || !GSShaderCompileIndicator::ShouldShowOnOSD())
|
||||
{
|
||||
s_indicator_was_visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const double imgui_time = ImGui::GetTime();
|
||||
if (!s_indicator_was_visible)
|
||||
s_indicator_fade_in_start = imgui_time;
|
||||
s_indicator_was_visible = true;
|
||||
|
||||
constexpr double fade_in_seconds = 0.12;
|
||||
const float fade_in_alpha = static_cast<float>(
|
||||
std::min(1.0, (imgui_time - s_indicator_fade_in_start) / fade_in_seconds));
|
||||
const float fade_out_alpha = GSShaderCompileIndicator::GetPostCompileFadeAlpha();
|
||||
const float indicator_alpha = std::clamp(fade_in_alpha * fade_out_alpha, 0.0f, 1.0f);
|
||||
const ImU32 text_col = IM_COL32(255, 255, 255, static_cast<int>(std::lround(255.0f * indicator_alpha)));
|
||||
const ImU32 shadow_col = IM_COL32(0, 0, 0, static_cast<int>(std::lround(100.0f * indicator_alpha)));
|
||||
const ImU32 spinner_track_col =
|
||||
IM_COL32(255, 255, 255, static_cast<int>(std::lround(45.0f * indicator_alpha)));
|
||||
|
||||
const std::string label = TRANSLATE_STR("ImGuiOverlays", "Compiling Shaders");
|
||||
ImFont* const font = ImGuiManager::GetOSDFont();
|
||||
const float font_size = ImGuiManager::GetFontSizeStandard();
|
||||
const float baseline_y =
|
||||
GetWindowHeight() - margin - (GSConfig.OsdShowSettings ? font_size : 0.0f);
|
||||
const float radius = std::ceil(10.0f * scale);
|
||||
const float cx = GetWindowWidth() - margin - radius;
|
||||
const float cy = baseline_y - spacing - radius;
|
||||
const ImVec2 center(cx, cy);
|
||||
|
||||
const ImVec2 text_size = font->CalcTextSizeA(
|
||||
font_size, std::numeric_limits<float>::max(), -1.0f, label.c_str(), label.c_str() + label.length(), nullptr);
|
||||
const float shadow_offset = std::ceil(scale);
|
||||
const float text_gap = std::ceil(6.0f * scale);
|
||||
const float text_x = cx - radius - text_gap - text_size.x;
|
||||
const float text_y = cy - font_size * 0.5f;
|
||||
|
||||
ImDrawList* const dl = ImGui::GetBackgroundDrawList();
|
||||
const float a0 = static_cast<float>(ImGui::GetTime()) * 10.0f;
|
||||
const float a1 = a0 + IM_PI * 1.12f;
|
||||
const float thickness = std::ceil(2.5f * scale);
|
||||
|
||||
dl->AddText(font, font_size, ImVec2(text_x + shadow_offset, text_y + shadow_offset), shadow_col,
|
||||
label.c_str(), label.c_str() + label.length());
|
||||
dl->AddText(font, font_size, ImVec2(text_x, text_y), text_col, label.c_str(), label.c_str() + label.length());
|
||||
if (GSConfig.OsdBoldText)
|
||||
{
|
||||
dl->AddText(font, font_size, ImVec2(text_x + 0.6f, text_y), text_col, label.c_str(),
|
||||
label.c_str() + label.length());
|
||||
}
|
||||
|
||||
dl->PathClear();
|
||||
dl->PathArcTo(center, radius, 0.0f, 2.0f * IM_PI, 32);
|
||||
dl->PathStroke(spinner_track_col, false, std::max(1.0f, thickness * 0.65f));
|
||||
|
||||
dl->PathClear();
|
||||
dl->PathArcTo(center, radius, a0, a1, 24);
|
||||
dl->PathStroke(text_col, false, thickness);
|
||||
}
|
||||
|
||||
__ri void ImGuiManager::DrawSettingsOverlay(float scale, float margin, float spacing)
|
||||
{
|
||||
if (!GSConfig.OsdShowSettings ||
|
||||
@@ -1698,6 +1766,7 @@ void ImGuiManager::RenderOverlays()
|
||||
if (GSConfig.OsdPerformancePos != OsdOverlayPos::None)
|
||||
DrawPerformanceOverlay(position_y, scale, margin, spacing);
|
||||
DrawSettingsOverlay(scale, margin, spacing);
|
||||
DrawShaderCompileIndicator(scale, margin, spacing);
|
||||
DrawInputsOverlay(scale, margin, spacing);
|
||||
if (SaveStateSelectorUI::s_open)
|
||||
SaveStateSelectorUI::Draw();
|
||||
|
||||
@@ -754,6 +754,7 @@ Pcsx2Config::GSOptions::GSOptions()
|
||||
HWMipmap = true;
|
||||
HWAccurateAlphaTest = false;
|
||||
HWAA1 = false;
|
||||
UseDebugBlend = false;
|
||||
|
||||
ManualUserHacks = false;
|
||||
UserHacks_AlignSpriteX = false;
|
||||
@@ -1041,6 +1042,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
|
||||
SettingsWrapBitBoolEx(HWMipmap, "hw_mipmap");
|
||||
SettingsWrapBitBool(HWAccurateAlphaTest);
|
||||
SettingsWrapBitBool(HWAA1);
|
||||
SettingsWrapBitBool(UseDebugBlend);
|
||||
SettingsWrapIntEnumEx(AccurateBlendingUnit, "accurate_blending_unit");
|
||||
SettingsWrapIntEnumEx(TextureFiltering, "filter");
|
||||
SettingsWrapIntEnumEx(TexturePreloading, "texture_preloading");
|
||||
|
||||
@@ -1034,6 +1034,16 @@ namespace usb_msd
|
||||
case ClassInterfaceOutRequest:
|
||||
switch (data[0])
|
||||
{
|
||||
case TEST_UNIT_READY:
|
||||
case START_STOP:
|
||||
case SEND_DIAGNOSTIC:
|
||||
break;
|
||||
case MODE_SENSE_10:
|
||||
s->f.mode = USB_MSDM_CBW;
|
||||
s->f.data_len = 0x08;
|
||||
memset(s->f.buf, 0, s->f.data_len);
|
||||
s->f.buf[1] = 0x06;
|
||||
break;
|
||||
case REQUEST_SENSE:
|
||||
{
|
||||
s->f.mode = USB_MSDM_CBW;
|
||||
|
||||
Reference in New Issue
Block a user