summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/am.cpp6
-rw-r--r--src/core/hle/service/am/am.h36
-rw-r--r--src/core/hle/service/apm/apm_controller.cpp10
-rw-r--r--src/core/hle/service/apm/apm_controller.h15
-rw-r--r--src/input_common/drivers/sdl_driver.cpp17
-rw-r--r--src/input_common/drivers/udp_client.cpp14
-rw-r--r--src/input_common/drivers/udp_client.h2
-rw-r--r--src/input_common/input_engine.cpp8
-rw-r--r--src/input_common/input_engine.h18
-rw-r--r--src/input_common/input_poller.cpp2
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h2
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp37
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h5
-rw-r--r--src/yuzu/main.cpp10
17 files changed, 136 insertions, 56 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 773dc9f29..2f8e21568 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -618,7 +618,7 @@ void AppletMessageQueue::PushMessage(AppletMessage msg) {
618AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { 618AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
619 if (messages.empty()) { 619 if (messages.empty()) {
620 on_new_message->GetWritableEvent().Clear(); 620 on_new_message->GetWritableEvent().Clear();
621 return AppletMessage::NoMessage; 621 return AppletMessage::None;
622 } 622 }
623 auto msg = messages.front(); 623 auto msg = messages.front();
624 messages.pop(); 624 messages.pop();
@@ -633,7 +633,7 @@ std::size_t AppletMessageQueue::GetMessageCount() const {
633} 633}
634 634
635void AppletMessageQueue::RequestExit() { 635void AppletMessageQueue::RequestExit() {
636 PushMessage(AppletMessage::ExitRequested); 636 PushMessage(AppletMessage::Exit);
637} 637}
638 638
639void AppletMessageQueue::FocusStateChanged() { 639void AppletMessageQueue::FocusStateChanged() {
@@ -732,7 +732,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
732 const auto message = msg_queue->PopMessage(); 732 const auto message = msg_queue->PopMessage();
733 IPC::ResponseBuilder rb{ctx, 3}; 733 IPC::ResponseBuilder rb{ctx, 3};
734 734
735 if (message == AppletMessageQueue::AppletMessage::NoMessage) { 735 if (message == AppletMessageQueue::AppletMessage::None) {
736 LOG_ERROR(Service_AM, "Message queue is empty"); 736 LOG_ERROR(Service_AM, "Message queue is empty");
737 rb.Push(ERR_NO_MESSAGES); 737 rb.Push(ERR_NO_MESSAGES);
738 rb.PushEnum<AppletMessageQueue::AppletMessage>(message); 738 rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 2a578aea5..fdd937b82 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -22,6 +22,7 @@ class NVFlinger;
22 22
23namespace Service::AM { 23namespace Service::AM {
24 24
25// This is nn::settings::Language
25enum SystemLanguage { 26enum SystemLanguage {
26 Japanese = 0, 27 Japanese = 0,
27 English = 1, // en-US 28 English = 1, // en-US
@@ -41,16 +42,44 @@ enum SystemLanguage {
41 // 4.0.0+ 42 // 4.0.0+
42 SimplifiedChinese = 15, 43 SimplifiedChinese = 15,
43 TraditionalChinese = 16, 44 TraditionalChinese = 16,
45 // 10.1.0+
46 BrazilianPortuguese = 17,
44}; 47};
45 48
46class AppletMessageQueue { 49class AppletMessageQueue {
47public: 50public:
51 // This is nn::am::AppletMessage
48 enum class AppletMessage : u32 { 52 enum class AppletMessage : u32 {
49 NoMessage = 0, 53 None = 0,
50 ExitRequested = 4, 54 ChangeIntoForeground = 1,
55 ChangeIntoBackground = 2,
56 Exit = 4,
57 ApplicationExited = 6,
51 FocusStateChanged = 15, 58 FocusStateChanged = 15,
59 Resume = 16,
60 DetectShortPressingHomeButton = 20,
61 DetectLongPressingHomeButton = 21,
62 DetectShortPressingPowerButton = 22,
63 DetectMiddlePressingPowerButton = 23,
64 DetectLongPressingPowerButton = 24,
65 RequestToPrepareSleep = 25,
66 FinishedSleepSequence = 26,
67 SleepRequiredByHighTemperature = 27,
68 SleepRequiredByLowBattery = 28,
69 AutoPowerDown = 29,
52 OperationModeChanged = 30, 70 OperationModeChanged = 30,
53 PerformanceModeChanged = 31, 71 PerformanceModeChanged = 31,
72 DetectReceivingCecSystemStandby = 32,
73 SdCardRemoved = 33,
74 LaunchApplicationRequested = 50,
75 RequestToDisplay = 51,
76 ShowApplicationLogo = 55,
77 HideApplicationLogo = 56,
78 ForceHideApplicationLogo = 57,
79 FloatingApplicationDetected = 60,
80 DetectShortPressingCaptureButton = 90,
81 AlbumScreenShotTaken = 92,
82 AlbumRecordingSaved = 93,
54 }; 83 };
55 84
56 explicit AppletMessageQueue(Core::System& system); 85 explicit AppletMessageQueue(Core::System& system);
@@ -179,11 +208,14 @@ public:
179 ~ICommonStateGetter() override; 208 ~ICommonStateGetter() override;
180 209
181private: 210private:
211 // This is nn::oe::FocusState
182 enum class FocusState : u8 { 212 enum class FocusState : u8 {
183 InFocus = 1, 213 InFocus = 1,
184 NotInFocus = 2, 214 NotInFocus = 2,
215 Background = 3,
185 }; 216 };
186 217
218 // This is nn::oe::OperationMode
187 enum class OperationMode : u8 { 219 enum class OperationMode : u8 {
188 Handheld = 0, 220 Handheld = 0,
189 Docked = 1, 221 Docked = 1,
diff --git a/src/core/hle/service/apm/apm_controller.cpp b/src/core/hle/service/apm/apm_controller.cpp
index 98839fe97..187fef2ad 100644
--- a/src/core/hle/service/apm/apm_controller.cpp
+++ b/src/core/hle/service/apm/apm_controller.cpp
@@ -17,8 +17,8 @@ constexpr auto DEFAULT_PERFORMANCE_CONFIGURATION = PerformanceConfiguration::Con
17 17
18Controller::Controller(Core::Timing::CoreTiming& core_timing_) 18Controller::Controller(Core::Timing::CoreTiming& core_timing_)
19 : core_timing{core_timing_}, configs{ 19 : core_timing{core_timing_}, configs{
20 {PerformanceMode::Handheld, DEFAULT_PERFORMANCE_CONFIGURATION}, 20 {PerformanceMode::Normal, DEFAULT_PERFORMANCE_CONFIGURATION},
21 {PerformanceMode::Docked, DEFAULT_PERFORMANCE_CONFIGURATION}, 21 {PerformanceMode::Boost, DEFAULT_PERFORMANCE_CONFIGURATION},
22 } {} 22 } {}
23 23
24Controller::~Controller() = default; 24Controller::~Controller() = default;
@@ -63,13 +63,13 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
63 PerformanceConfiguration::Config15, 63 PerformanceConfiguration::Config15,
64 }}; 64 }};
65 65
66 SetPerformanceConfiguration(PerformanceMode::Docked, 66 SetPerformanceConfiguration(PerformanceMode::Boost,
67 BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode))); 67 BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode)));
68} 68}
69 69
70PerformanceMode Controller::GetCurrentPerformanceMode() const { 70PerformanceMode Controller::GetCurrentPerformanceMode() const {
71 return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Docked 71 return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Boost
72 : PerformanceMode::Handheld; 72 : PerformanceMode::Normal;
73} 73}
74 74
75PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) { 75PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
diff --git a/src/core/hle/service/apm/apm_controller.h b/src/core/hle/service/apm/apm_controller.h
index 8d48e0104..d6fbd2c0c 100644
--- a/src/core/hle/service/apm/apm_controller.h
+++ b/src/core/hle/service/apm/apm_controller.h
@@ -32,15 +32,18 @@ enum class PerformanceConfiguration : u32 {
32 Config16 = 0x9222000C, 32 Config16 = 0x9222000C,
33}; 33};
34 34
35// This is nn::oe::CpuBoostMode
35enum class CpuBoostMode : u32 { 36enum class CpuBoostMode : u32 {
36 Disabled = 0, 37 Normal = 0, // Boost mode disabled
37 Full = 1, // CPU + GPU -> Config 13, 14, 15, or 16 38 FastLoad = 1, // CPU + GPU -> Config 13, 14, 15, or 16
38 Partial = 2, // GPU Only -> Config 15 or 16 39 Partial = 2, // GPU Only -> Config 15 or 16
39}; 40};
40 41
41enum class PerformanceMode : u8 { 42// This is nn::oe::PerformanceMode
42 Handheld = 0, 43enum class PerformanceMode : s32 {
43 Docked = 1, 44 Invalid = -1,
45 Normal = 0,
46 Boost = 1,
44}; 47};
45 48
46// Class to manage the state and change of the emulated system performance. 49// Class to manage the state and change of the emulated system performance.
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index 5cf1987ad..c17ea305e 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -175,22 +175,23 @@ public:
175 return false; 175 return false;
176 } 176 }
177 177
178 BatteryLevel GetBatteryLevel() { 178 Common::Input::BatteryLevel GetBatteryLevel() {
179 const auto level = SDL_JoystickCurrentPowerLevel(sdl_joystick.get()); 179 const auto level = SDL_JoystickCurrentPowerLevel(sdl_joystick.get());
180 switch (level) { 180 switch (level) {
181 case SDL_JOYSTICK_POWER_EMPTY: 181 case SDL_JOYSTICK_POWER_EMPTY:
182 return BatteryLevel::Empty; 182 return Common::Input::BatteryLevel::Empty;
183 case SDL_JOYSTICK_POWER_LOW: 183 case SDL_JOYSTICK_POWER_LOW:
184 return BatteryLevel::Low; 184 return Common::Input::BatteryLevel::Low;
185 case SDL_JOYSTICK_POWER_MEDIUM: 185 case SDL_JOYSTICK_POWER_MEDIUM:
186 return BatteryLevel::Medium; 186 return Common::Input::BatteryLevel::Medium;
187 case SDL_JOYSTICK_POWER_FULL: 187 case SDL_JOYSTICK_POWER_FULL:
188 case SDL_JOYSTICK_POWER_MAX: 188 case SDL_JOYSTICK_POWER_MAX:
189 return BatteryLevel::Full; 189 return Common::Input::BatteryLevel::Full;
190 case SDL_JOYSTICK_POWER_UNKNOWN:
191 case SDL_JOYSTICK_POWER_WIRED: 190 case SDL_JOYSTICK_POWER_WIRED:
191 return Common::Input::BatteryLevel::Charging;
192 case SDL_JOYSTICK_POWER_UNKNOWN:
192 default: 193 default:
193 return BatteryLevel::Charging; 194 return Common::Input::BatteryLevel::None;
194 } 195 }
195 } 196 }
196 197
@@ -351,6 +352,8 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) {
351 if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { 352 if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) {
352 const PadIdentifier identifier = joystick->GetPadIdentifier(); 353 const PadIdentifier identifier = joystick->GetPadIdentifier();
353 SetButton(identifier, event.jbutton.button, true); 354 SetButton(identifier, event.jbutton.button, true);
355 // Battery doesn't trigger an event so just update every button press
356 SetBattery(identifier, joystick->GetBatteryLevel());
354 } 357 }
355 break; 358 break;
356 } 359 }
diff --git a/src/input_common/drivers/udp_client.cpp b/src/input_common/drivers/udp_client.cpp
index 64162f431..9780ead10 100644
--- a/src/input_common/drivers/udp_client.cpp
+++ b/src/input_common/drivers/udp_client.cpp
@@ -192,22 +192,22 @@ std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
192 return MAX_UDP_CLIENTS; 192 return MAX_UDP_CLIENTS;
193} 193}
194 194
195BatteryLevel UDPClient::GetBatteryLevel(Response::Battery battery) const { 195Common::Input::BatteryLevel UDPClient::GetBatteryLevel(Response::Battery battery) const {
196 switch (battery) { 196 switch (battery) {
197 case Response::Battery::Dying: 197 case Response::Battery::Dying:
198 return BatteryLevel::Empty; 198 return Common::Input::BatteryLevel::Empty;
199 case Response::Battery::Low: 199 case Response::Battery::Low:
200 return BatteryLevel::Critical; 200 return Common::Input::BatteryLevel::Critical;
201 case Response::Battery::Medium: 201 case Response::Battery::Medium:
202 return BatteryLevel::Low; 202 return Common::Input::BatteryLevel::Low;
203 case Response::Battery::High: 203 case Response::Battery::High:
204 return BatteryLevel::Medium; 204 return Common::Input::BatteryLevel::Medium;
205 case Response::Battery::Full: 205 case Response::Battery::Full:
206 case Response::Battery::Charged: 206 case Response::Battery::Charged:
207 return BatteryLevel::Full; 207 return Common::Input::BatteryLevel::Full;
208 case Response::Battery::Charging: 208 case Response::Battery::Charging:
209 default: 209 default:
210 return BatteryLevel::Charging; 210 return Common::Input::BatteryLevel::Charging;
211 } 211 }
212} 212}
213 213
diff --git a/src/input_common/drivers/udp_client.h b/src/input_common/drivers/udp_client.h
index 76e32bd04..c7cc7d846 100644
--- a/src/input_common/drivers/udp_client.h
+++ b/src/input_common/drivers/udp_client.h
@@ -141,7 +141,7 @@ private:
141 std::size_t GetClientNumber(std::string_view host, u16 port) const; 141 std::size_t GetClientNumber(std::string_view host, u16 port) const;
142 142
143 // Translates UDP battery level to input engine battery level 143 // Translates UDP battery level to input engine battery level
144 BatteryLevel GetBatteryLevel(Response::Battery battery) const; 144 Common::Input::BatteryLevel GetBatteryLevel(Response::Battery battery) const;
145 145
146 void OnVersion(Response::Version); 146 void OnVersion(Response::Version);
147 void OnPortInfo(Response::PortInfo); 147 void OnPortInfo(Response::PortInfo);
diff --git a/src/input_common/input_engine.cpp b/src/input_common/input_engine.cpp
index 65ae1b848..7adf7e3d7 100644
--- a/src/input_common/input_engine.cpp
+++ b/src/input_common/input_engine.cpp
@@ -70,7 +70,7 @@ void InputEngine::SetAxis(const PadIdentifier& identifier, int axis, f32 value)
70 TriggerOnAxisChange(identifier, axis, value); 70 TriggerOnAxisChange(identifier, axis, value);
71} 71}
72 72
73void InputEngine::SetBattery(const PadIdentifier& identifier, BatteryLevel value) { 73void InputEngine::SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value) {
74 { 74 {
75 std::lock_guard lock{mutex}; 75 std::lock_guard lock{mutex};
76 ControllerData& controller = controller_list.at(identifier); 76 ControllerData& controller = controller_list.at(identifier);
@@ -143,13 +143,13 @@ f32 InputEngine::GetAxis(const PadIdentifier& identifier, int axis) const {
143 return axis_iter->second; 143 return axis_iter->second;
144} 144}
145 145
146BatteryLevel InputEngine::GetBattery(const PadIdentifier& identifier) const { 146Common::Input::BatteryLevel InputEngine::GetBattery(const PadIdentifier& identifier) const {
147 std::lock_guard lock{mutex}; 147 std::lock_guard lock{mutex};
148 const auto controller_iter = controller_list.find(identifier); 148 const auto controller_iter = controller_list.find(identifier);
149 if (controller_iter == controller_list.cend()) { 149 if (controller_iter == controller_list.cend()) {
150 LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), 150 LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
151 identifier.pad, identifier.port); 151 identifier.pad, identifier.port);
152 return BatteryLevel::Charging; 152 return Common::Input::BatteryLevel::Charging;
153 } 153 }
154 const ControllerData& controller = controller_iter->second; 154 const ControllerData& controller = controller_iter->second;
155 return controller.battery; 155 return controller.battery;
@@ -270,7 +270,7 @@ void InputEngine::TriggerOnAxisChange(const PadIdentifier& identifier, int axis,
270} 270}
271 271
272void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier, 272void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier,
273 [[maybe_unused]] BatteryLevel value) { 273 [[maybe_unused]] Common::Input::BatteryLevel value) {
274 std::lock_guard lock{mutex_callback}; 274 std::lock_guard lock{mutex_callback};
275 for (const auto& poller_pair : callback_list) { 275 for (const auto& poller_pair : callback_list) {
276 const InputIdentifier& poller = poller_pair.second; 276 const InputIdentifier& poller = poller_pair.second;
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h
index c6c027aef..f44e0799b 100644
--- a/src/input_common/input_engine.h
+++ b/src/input_common/input_engine.h
@@ -34,16 +34,6 @@ struct BasicMotion {
34 u64 delta_timestamp{}; 34 u64 delta_timestamp{};
35}; 35};
36 36
37// Stages of a battery charge
38enum class BatteryLevel {
39 Empty,
40 Critical,
41 Low,
42 Medium,
43 Full,
44 Charging,
45};
46
47// Types of input that are stored in the engine 37// Types of input that are stored in the engine
48enum class EngineInputType { 38enum class EngineInputType {
49 None, 39 None,
@@ -178,7 +168,7 @@ public:
178 bool GetButton(const PadIdentifier& identifier, int button) const; 168 bool GetButton(const PadIdentifier& identifier, int button) const;
179 bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const; 169 bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const;
180 f32 GetAxis(const PadIdentifier& identifier, int axis) const; 170 f32 GetAxis(const PadIdentifier& identifier, int axis) const;
181 BatteryLevel GetBattery(const PadIdentifier& identifier) const; 171 Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const;
182 BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; 172 BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
183 173
184 int SetCallback(InputIdentifier input_identifier); 174 int SetCallback(InputIdentifier input_identifier);
@@ -189,7 +179,7 @@ protected:
189 void SetButton(const PadIdentifier& identifier, int button, bool value); 179 void SetButton(const PadIdentifier& identifier, int button, bool value);
190 void SetHatButton(const PadIdentifier& identifier, int button, u8 value); 180 void SetHatButton(const PadIdentifier& identifier, int button, u8 value);
191 void SetAxis(const PadIdentifier& identifier, int axis, f32 value); 181 void SetAxis(const PadIdentifier& identifier, int axis, f32 value);
192 void SetBattery(const PadIdentifier& identifier, BatteryLevel value); 182 void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
193 void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value); 183 void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value);
194 184
195 virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const { 185 virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
@@ -202,13 +192,13 @@ private:
202 std::unordered_map<int, u8> hat_buttons; 192 std::unordered_map<int, u8> hat_buttons;
203 std::unordered_map<int, float> axes; 193 std::unordered_map<int, float> axes;
204 std::unordered_map<int, BasicMotion> motions; 194 std::unordered_map<int, BasicMotion> motions;
205 BatteryLevel battery{}; 195 Common::Input::BatteryLevel battery{};
206 }; 196 };
207 197
208 void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value); 198 void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
209 void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value); 199 void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value);
210 void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value); 200 void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value);
211 void TriggerOnBatteryChange(const PadIdentifier& identifier, BatteryLevel value); 201 void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
212 void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, 202 void TriggerOnMotionChange(const PadIdentifier& identifier, int motion,
213 const BasicMotion& value); 203 const BasicMotion& value);
214 204
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
index 7f3c08597..82b585ff2 100644
--- a/src/input_common/input_poller.cpp
+++ b/src/input_common/input_poller.cpp
@@ -470,7 +470,7 @@ public:
470 } 470 }
471 471
472 Common::Input::BatteryStatus GetStatus() const { 472 Common::Input::BatteryStatus GetStatus() const {
473 return static_cast<Common::Input::BatteryLevel>(input_engine->GetBattery(identifier)); 473 return input_engine->GetBattery(identifier);
474 } 474 }
475 475
476 void ForceUpdate() override { 476 void ForceUpdate() override {
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index daba42ed9..db5bf1d30 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -184,6 +184,8 @@ inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
184 case Maxwell::VertexAttribute::Size::Size_32_32_32: 184 case Maxwell::VertexAttribute::Size::Size_32_32_32:
185 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 185 case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
186 return GL_FLOAT; 186 return GL_FLOAT;
187 case Maxwell::VertexAttribute::Size::Size_11_11_10:
188 return GL_UNSIGNED_INT_10F_11F_11F_REV;
187 default: 189 default:
188 break; 190 break;
189 } 191 }
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index 751e4792b..1c136c410 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -495,6 +495,8 @@ VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttrib
495 return VK_FORMAT_R32G32B32_SFLOAT; 495 return VK_FORMAT_R32G32B32_SFLOAT;
496 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 496 case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
497 return VK_FORMAT_R32G32B32A32_SFLOAT; 497 return VK_FORMAT_R32G32B32A32_SFLOAT;
498 case Maxwell::VertexAttribute::Size::Size_11_11_10:
499 return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
498 default: 500 default:
499 break; 501 break;
500 } 502 }
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index c71a1f44d..621a6a071 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -100,6 +100,8 @@ VkFormat GetFormat(const Tegra::FramebufferConfig& framebuffer) {
100 return VK_FORMAT_A8B8G8R8_UNORM_PACK32; 100 return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
101 case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM: 101 case Tegra::FramebufferConfig::PixelFormat::RGB565_UNORM:
102 return VK_FORMAT_R5G6B5_UNORM_PACK16; 102 return VK_FORMAT_R5G6B5_UNORM_PACK16;
103 case Tegra::FramebufferConfig::PixelFormat::B8G8R8A8_UNORM:
104 return VK_FORMAT_B8G8R8A8_UNORM;
103 default: 105 default:
104 UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", 106 UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}",
105 static_cast<u32>(framebuffer.pixel_format)); 107 static_cast<u32>(framebuffer.pixel_format));
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 0ba56ff1e..0f62779de 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -554,10 +554,12 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im
554 }; 554 };
555} 555}
556 556
557[[nodiscard]] bool IsFormatFlipped(PixelFormat format) { 557[[nodiscard]] bool IsFormatFlipped(PixelFormat format, bool emulate_bgr565) {
558 switch (format) { 558 switch (format) {
559 case PixelFormat::A1B5G5R5_UNORM: 559 case PixelFormat::A1B5G5R5_UNORM:
560 return true; 560 return true;
561 case PixelFormat::B5G6R5_UNORM:
562 return emulate_bgr565;
561 default: 563 default:
562 return false; 564 return false;
563 } 565 }
@@ -1488,7 +1490,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI
1488 }; 1490 };
1489 if (!info.IsRenderTarget()) { 1491 if (!info.IsRenderTarget()) {
1490 swizzle = info.Swizzle(); 1492 swizzle = info.Swizzle();
1491 if (IsFormatFlipped(format)) { 1493 if (IsFormatFlipped(format, device->MustEmulateBGR565())) {
1492 std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); 1494 std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed);
1493 } 1495 }
1494 if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) { 1496 if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 153702c0b..effde73c9 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -39,6 +39,11 @@ constexpr std::array DEPTH16_UNORM_STENCIL8_UINT{
39 VK_FORMAT_D32_SFLOAT_S8_UINT, 39 VK_FORMAT_D32_SFLOAT_S8_UINT,
40 VK_FORMAT_UNDEFINED, 40 VK_FORMAT_UNDEFINED,
41}; 41};
42
43constexpr std::array B5G6R5_UNORM_PACK16{
44 VK_FORMAT_R5G6B5_UNORM_PACK16,
45 VK_FORMAT_UNDEFINED,
46};
42} // namespace Alternatives 47} // namespace Alternatives
43 48
44enum class NvidiaArchitecture { 49enum class NvidiaArchitecture {
@@ -87,6 +92,8 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) {
87 return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data(); 92 return Alternatives::DEPTH24_UNORM_STENCIL8_UINT.data();
88 case VK_FORMAT_D16_UNORM_S8_UINT: 93 case VK_FORMAT_D16_UNORM_S8_UINT:
89 return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data(); 94 return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data();
95 case VK_FORMAT_B5G6R5_UNORM_PACK16:
96 return Alternatives::B5G6R5_UNORM_PACK16.data();
90 default: 97 default:
91 return nullptr; 98 return nullptr;
92 } 99 }
@@ -224,9 +231,14 @@ std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
224 return supported_extensions; 231 return supported_extensions;
225} 232}
226 233
234bool IsExtensionSupported(std::span<const std::string> supported_extensions,
235 std::string_view extension) {
236 return std::ranges::find(supported_extensions, extension) != supported_extensions.end();
237}
238
227NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, 239NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
228 std::span<const std::string> exts) { 240 std::span<const std::string> exts) {
229 if (std::ranges::find(exts, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME) != exts.end()) { 241 if (IsExtensionSupported(exts, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
230 VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{}; 242 VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{};
231 shading_rate_props.sType = 243 shading_rate_props.sType =
232 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR; 244 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
@@ -239,7 +251,7 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
239 return NvidiaArchitecture::AmpereOrNewer; 251 return NvidiaArchitecture::AmpereOrNewer;
240 } 252 }
241 } 253 }
242 if (std::ranges::find(exts, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME) != exts.end()) { 254 if (IsExtensionSupported(exts, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME)) {
243 return NvidiaArchitecture::Turing; 255 return NvidiaArchitecture::Turing;
244 } 256 }
245 return NvidiaArchitecture::VoltaOrOlder; 257 return NvidiaArchitecture::VoltaOrOlder;
@@ -604,7 +616,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
604 break; 616 break;
605 } 617 }
606 } 618 }
607 if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_MESA_RADV) { 619 const bool is_radv = driver_id == VK_DRIVER_ID_MESA_RADV;
620 if (ext_extended_dynamic_state && is_radv) {
608 // Mask driver version variant 621 // Mask driver version variant
609 const u32 version = (properties.driverVersion << 3) >> 3; 622 const u32 version = (properties.driverVersion << 3) >> 3;
610 if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) { 623 if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) {
@@ -613,6 +626,17 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
613 ext_extended_dynamic_state = false; 626 ext_extended_dynamic_state = false;
614 } 627 }
615 } 628 }
629 if (ext_vertex_input_dynamic_state && is_radv) {
630 // TODO(ameerj): Blacklist only offending driver versions
631 // TODO(ameerj): Confirm if RDNA1 is affected
632 const bool is_rdna2 =
633 IsExtensionSupported(supported_extensions, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME);
634 if (is_rdna2) {
635 LOG_WARNING(Render_Vulkan,
636 "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware");
637 ext_vertex_input_dynamic_state = false;
638 }
639 }
616 sets_per_pool = 64; 640 sets_per_pool = 64;
617 641
618 const bool is_amd = 642 const bool is_amd =
@@ -628,7 +652,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
628 has_broken_cube_compatibility = true; 652 has_broken_cube_compatibility = true;
629 } 653 }
630 } 654 }
631 const bool is_amd_or_radv = is_amd || driver_id == VK_DRIVER_ID_MESA_RADV; 655 const bool is_amd_or_radv = is_amd || is_radv;
632 if (ext_sampler_filter_minmax && is_amd_or_radv) { 656 if (ext_sampler_filter_minmax && is_amd_or_radv) {
633 // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken. 657 // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken.
634 if (!is_float16_supported) { 658 if (!is_float16_supported) {
@@ -639,6 +663,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
639 } 663 }
640 664
641 const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS; 665 const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS;
666 const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
642 if (ext_vertex_input_dynamic_state && is_intel_windows) { 667 if (ext_vertex_input_dynamic_state && is_intel_windows) {
643 LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state"); 668 LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state");
644 ext_vertex_input_dynamic_state = false; 669 ext_vertex_input_dynamic_state = false;
@@ -652,6 +677,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
652 LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); 677 LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits");
653 cant_blit_msaa = true; 678 cant_blit_msaa = true;
654 } 679 }
680 if (is_intel_anv) {
681 LOG_WARNING(Render_Vulkan, "ANV driver does not support native BGR format");
682 must_emulate_bgr565 = true;
683 }
655 684
656 supports_d24_depth = 685 supports_d24_depth =
657 IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT, 686 IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 37d140ebd..34b1add16 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -354,6 +354,10 @@ public:
354 return cant_blit_msaa; 354 return cant_blit_msaa;
355 } 355 }
356 356
357 bool MustEmulateBGR565() const {
358 return must_emulate_bgr565;
359 }
360
357private: 361private:
358 /// Checks if the physical device is suitable. 362 /// Checks if the physical device is suitable.
359 void CheckSuitability(bool requires_swapchain) const; 363 void CheckSuitability(bool requires_swapchain) const;
@@ -448,6 +452,7 @@ private:
448 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached 452 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
449 bool supports_d24_depth{}; ///< Supports D24 depth buffers. 453 bool supports_d24_depth{}; ///< Supports D24 depth buffers.
450 bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting. 454 bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting.
455 bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format.
451 456
452 // Telemetry parameters 457 // Telemetry parameters
453 std::string vendor_name; ///< Device's driver name. 458 std::string vendor_name; ///< Device's driver name.
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e3fd38a02..b3a8da0ea 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2937,6 +2937,7 @@ void GMainWindow::OnLoadAmiibo() {
2937 if (nfc_state == Service::NFP::DeviceState::TagFound || 2937 if (nfc_state == Service::NFP::DeviceState::TagFound ||
2938 nfc_state == Service::NFP::DeviceState::TagMounted) { 2938 nfc_state == Service::NFP::DeviceState::TagMounted) {
2939 nfc->CloseAmiibo(); 2939 nfc->CloseAmiibo();
2940 QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed"));
2940 return; 2941 return;
2941 } 2942 }
2942 2943
@@ -2965,6 +2966,15 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
2965 return; 2966 return;
2966 } 2967 }
2967 2968
2969 // Remove amiibo if one is connected
2970 const auto nfc_state = nfc->GetCurrentState();
2971 if (nfc_state == Service::NFP::DeviceState::TagFound ||
2972 nfc_state == Service::NFP::DeviceState::TagMounted) {
2973 nfc->CloseAmiibo();
2974 QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed"));
2975 return;
2976 }
2977
2968 QFile nfc_file{filename}; 2978 QFile nfc_file{filename};
2969 if (!nfc_file.open(QIODevice::ReadOnly)) { 2979 if (!nfc_file.open(QIODevice::ReadOnly)) {
2970 QMessageBox::warning(this, tr("Error opening Amiibo data file"), 2980 QMessageBox::warning(this, tr("Error opening Amiibo data file"),