Compare commits

...

35 Commits

Author SHA1 Message Date
Morph 5deecd714b input_interpreter: Make use of NpadButton instead of a u64
Allows us to be more explicit with the representation of button states and use the provided bit manipulation operators
2021-11-29 19:21:51 -05:00
Morph 322339a5fd npad: Return NpadButton in GetAndResetPressState
We were previously truncating this to a u32 as there were no known buttons that used the full 64 bits of this type. Fix this now that we know they are used.
2021-11-29 19:21:51 -05:00
Morph bfac21fca1 core: hid: hid_types: Add "All" to NpadButton
This represents a bitmask for all pressed buttons
2021-11-29 19:21:51 -05:00
Morph b86fcf7c31 qt_controller: Make use of (Enable/Disable)AllControllerConfiguration
This also moves the use of DisableConfiguration to the destructor.
2021-11-29 19:21:50 -05:00
Morph 940375dfbb core: hid: hid_core: Add (Enable/DIsable)AllControllerConfiguration 2021-11-29 17:59:58 -05:00
Morph 410df5446e general: Fix handheld typo 2021-11-29 17:22:59 -05:00
Morph 04f48f0120 core: hid: Mark constructors as explicit 2021-11-29 17:20:15 -05:00
Morph b9b28c0457 core: hid: Cleanup and amend documentation 2021-11-29 17:20:14 -05:00
Morph 614702488f Merge pull request #7465 from german77/no_input
qt_controller: Fix input when the controller applet is ignored
2021-11-29 07:25:36 -05:00
german77 dcc4685557 qt_controller: Fix input when the controller applet is ignored 2021-11-28 21:03:42 -06:00
Fernando S 3031223153 Merge pull request #7396 from FernandoS27/blit-this-mf
TextureCache: Eliminate format deduction as full depth conversion has been supported.
2021-11-28 12:16:31 +01:00
Fernando Sahmkow 5a3463bc2b Texture Cache: Secure insertions against deletions. 2021-11-28 10:53:27 +01:00
bunnei 11a9bff36d Merge pull request #7438 from german77/homebrew2
Core: Stub services and functions needed for checkpoint
2021-11-28 00:54:48 -08:00
bunnei be56587ad7 Merge pull request #7451 from german77/debug_controller
settings: Add debug setting to enable all controllers
2021-11-28 00:54:29 -08:00
Narr the Reg 54f007efc6 core/ns: Implement GetReadOnlyApplicationControlDataInterface
Used in checkpoint homebrew
2021-11-27 20:30:16 -06:00
Narr the Reg 50d8e753c5 core/pdm: Stub QueryPlayStatisticsByApplicationIdAndUserAccountId
Used in checkpoint homebrew
2021-11-27 20:30:16 -06:00
german77 51df96b7c0 settings: Add debug setting to enable all controllers 2021-11-27 20:24:37 -06:00
Narr the Reg f966c05a74 core/hid: Stub GetUniquePadsFromNpad
Used in checkpoint homebrew
2021-11-27 09:03:10 -06:00
Fernando S 564f105277 Merge pull request #7255 from german77/kraken
Project Kraken: Input rewrite
2021-11-27 11:52:08 +01:00
Fernando Sahmkow ecefc932e6 Texture Cache: Redesigning the blitting system (again). 2021-11-27 11:22:16 +01:00
bunnei 157985f556 Merge pull request #7431 from liushuyu/fix-linux-decoding
video_core/codecs: fix multiple decoding issues on Linux
2021-11-26 15:38:40 -08:00
Fernando Sahmkow 1624f307d0 Texture Cache: Further fix regressions. 2021-11-26 17:03:48 +01:00
bunnei 50a19b07d1 Merge pull request #7440 from lioncash/fmt
CMakeLists: Update fmt to 8.0.1
2021-11-25 20:58:49 -08:00
Lioncash 5303161aa1 CMakeLists: Update fmt to 8.0.1
Ensures that we're using the latest version of fmt.
2021-11-25 23:08:45 -05:00
bunnei 06ad463ec8 Merge pull request #7330 from MightyCreak/simplify-theme-selection
Replace "Light" theme by "Default"
2021-11-25 01:52:48 -08:00
liushuyu 60928cf8cd video_core/codec: address comments 2021-11-24 18:06:38 -07:00
liushuyu 72aa418b0b video_core/codecs: fix multiple decoding issues on Linux ...
* when someone installed Intel video drivers on an AMD system, the
  decoder will select the Intel VA-API decoding driver and yuzu will
  crash due to incorrect driver selection; the fix will check if the
  currently about-to-use driver is loaded in the kernel
* when using NVIDIA driver on Linux with a ffmpeg that does not have
  CUDA capability enabled, the decoder will crash; the fix simply
  making the decoder prefers the VDPAU driver over CUDA on Linux
2021-11-24 17:23:57 -07:00
Fernando Sahmkow 08674aee87 Texture Cache: Fix issue with blitting 3D textures. 2021-11-22 06:07:21 +01:00
Fernando Sahmkow 1e474fb9d1 Texture Cache: Correct conversion shaders. 2021-11-22 00:21:42 +01:00
Fernando Sahmkow 0902119302 Texture Cache: Always copy on NVIDIA. 2021-11-22 00:06:56 +01:00
Fernando Sahmkow 8532849439 TextureCache: Simplify blitting of D24S8 formats and fix bugs. 2021-11-22 00:00:01 +01:00
Fernando Sahmkow d7f4434bd5 VulkanTexturECache: Use reinterpret on D32_S8 formats. 2021-11-21 21:09:49 +01:00
Fernando Sahmkow b96caf200d HostShaders: Fix D24S8 convertion shaders. 2021-11-21 21:04:04 +01:00
Fernando Sahmkow 779f4ac72d TextureCache: Eliminate format deduction as full depth conversion has been supported. 2021-11-21 05:37:01 +01:00
Romain Failliot 2e5866147e Replace "Light" theme by "Default"
This reflects the current behavior: Light = System default. If your
system is set to dark theme, then Light = Dark, which is a bit confusing
for the end user.

In this PR, I propose to change "Light" with "Default". This way, the
user has "Default" and "Default Colorful", which will apply the system
theme. Now that the Flatpak respects the system theme, I think this
makes much more sense.

I also simplified the theme update. Before the code was branching
between the default theme and the others, but I think we can have
something simpler by forcing the default theme if no theme is defined in
the settings, or if the selected theme doesn't exist. And if there's an
error, tell the theme name in the error message.
2021-11-14 08:52:55 -05:00
44 changed files with 610 additions and 365 deletions
+1 -1
View File
@@ -167,7 +167,7 @@ macro(yuzu_find_packages)
set(REQUIRED_LIBS
# Cmake Pkg Prefix Version Conan Pkg
"Catch2 2.13.7 catch2/2.13.7"
"fmt 8.0 fmt/8.0.0"
"fmt 8.0.1 fmt/8.0.1"
"lz4 1.8 lz4/1.9.2"
"nlohmann_json 3.8 nlohmann_json/3.8.0"
"ZLIB 1.2 zlib/1.2.11"
+1
View File
@@ -604,6 +604,7 @@ struct Values {
BasicSetting<bool> extended_logging{false, "extended_logging"};
BasicSetting<bool> use_debug_asserts{false, "use_debug_asserts"};
BasicSetting<bool> use_auto_stub{false, "use_auto_stub"};
BasicSetting<bool> enable_all_controllers{false, "enable_all_controllers"};
// Miscellaneous
BasicSetting<std::string> log_filter{"*:Info", "log_filter"};
+5
View File
@@ -370,6 +370,11 @@ enum class ControllerType {
RightJoycon,
Handheld,
GameCube,
Pokeball,
NES,
SNES,
N64,
SegaGenesis,
};
struct PlayerInput {
+2
View File
@@ -479,6 +479,8 @@ add_library(core STATIC
hle/service/ns/language.h
hle/service/ns/ns.cpp
hle/service/ns/ns.h
hle/service/ns/pdm_qry.cpp
hle/service/ns/pdm_qry.h
hle/service/ns/pl_u.cpp
hle/service/ns/pl_u.h
hle/service/nvdrv/devices/nvdevice.h
+15 -13
View File
@@ -78,9 +78,9 @@ struct ConsoleUpdateCallback {
class EmulatedConsole {
public:
/**
* Contains all input data related to the console like motion and touch input
* Contains all input data within the emulated switch console tablet such as touch and motion
*/
EmulatedConsole();
explicit EmulatedConsole();
~EmulatedConsole();
YUZU_NON_COPYABLE(EmulatedConsole);
@@ -89,14 +89,16 @@ public:
/// Removes all callbacks created from input devices
void UnloadInput();
/// Sets the emulated console into configuring mode. Locking all HID service events from being
/// moddified
/**
* Sets the emulated console into configuring mode
* This prevents the modification of the HID state of the emulated console by input commands
*/
void EnableConfiguration();
/// Returns the emulated console to the normal behaivour
/// Returns the emulated console into normal mode, allowing the modification of the HID state
void DisableConfiguration();
/// Returns true if the emulated console is on configuring mode
/// Returns true if the emulated console is in configuring mode
bool IsConfiguring() const;
/// Reload all input devices
@@ -116,7 +118,7 @@ public:
/**
* Updates the current mapped motion device
* @param ParamPackage with controller data to be mapped
* @param param ParamPackage with controller data to be mapped
*/
void SetMotionParam(Common::ParamPackage param);
@@ -134,14 +136,14 @@ public:
/**
* Adds a callback to the list of events
* @param ConsoleUpdateCallback that will be triggered
* @param update_callback A ConsoleUpdateCallback that will be triggered
* @return an unique key corresponding to the callback index in the list
*/
int SetCallback(ConsoleUpdateCallback update_callback);
/**
* Removes a callback from the list stopping any future events to this object
* @param Key corresponding to the callback index in the list
* @param key Key corresponding to the callback index in the list
*/
void DeleteCallback(int key);
@@ -151,20 +153,20 @@ private:
/**
* Updates the motion status of the console
* @param A CallbackStatus containing gyro and accelerometer data
* @param callback A CallbackStatus containing gyro and accelerometer data
*/
void SetMotion(Common::Input::CallbackStatus callback);
/**
* Updates the touch status of the console
* @param callback: A CallbackStatus containing the touch position
* @param index: Finger ID to be updated
* @param callback A CallbackStatus containing the touch position
* @param index Finger ID to be updated
*/
void SetTouch(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Triggers a callback that something has changed on the console status
* @param Input type of the event to trigger
* @param type Input type of the event to trigger
*/
void TriggerOnChange(ConsoleTriggerType type);
+20
View File
@@ -27,6 +27,16 @@ NpadStyleIndex EmulatedController::MapSettingsTypeToNPad(Settings::ControllerTyp
return NpadStyleIndex::Handheld;
case Settings::ControllerType::GameCube:
return NpadStyleIndex::GameCube;
case Settings::ControllerType::Pokeball:
return NpadStyleIndex::Pokeball;
case Settings::ControllerType::NES:
return NpadStyleIndex::NES;
case Settings::ControllerType::SNES:
return NpadStyleIndex::SNES;
case Settings::ControllerType::N64:
return NpadStyleIndex::N64;
case Settings::ControllerType::SegaGenesis:
return NpadStyleIndex::SegaGenesis;
default:
return NpadStyleIndex::ProController;
}
@@ -46,6 +56,16 @@ Settings::ControllerType EmulatedController::MapNPadToSettingsType(NpadStyleInde
return Settings::ControllerType::Handheld;
case NpadStyleIndex::GameCube:
return Settings::ControllerType::GameCube;
case NpadStyleIndex::Pokeball:
return Settings::ControllerType::Pokeball;
case NpadStyleIndex::NES:
return Settings::ControllerType::NES;
case NpadStyleIndex::SNES:
return Settings::ControllerType::SNES;
case NpadStyleIndex::N64:
return Settings::ControllerType::N64;
case NpadStyleIndex::SegaGenesis:
return Settings::ControllerType::SegaGenesis;
default:
return Settings::ControllerType::ProController;
}
+30 -28
View File
@@ -132,8 +132,8 @@ struct ControllerUpdateCallback {
class EmulatedController {
public:
/**
* Contains all input data related to this controller. Like buttons, joysticks, motion.
* @param Npad id type for this specific controller
* Contains all input data (buttons, joysticks, vibration, and motion) within this controller.
* @param npad_id_type npad id type for this specific controller
*/
explicit EmulatedController(NpadIdType npad_id_type_);
~EmulatedController();
@@ -155,7 +155,7 @@ public:
/**
* Gets the NpadStyleIndex for this controller
* @param If true tmp_npad_type will be returned
* @param get_temporary_value If true tmp_npad_type will be returned
* @return NpadStyleIndex set on the controller
*/
NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const;
@@ -168,7 +168,7 @@ public:
/**
* Is the emulated connected
* @param If true tmp_is_connected will be returned
* @param get_temporary_value If true tmp_is_connected will be returned
* @return true if the controller has the connected status
*/
bool IsConnected(bool get_temporary_value = false) const;
@@ -179,14 +179,16 @@ public:
/// Removes all callbacks created from input devices
void UnloadInput();
/// Sets the emulated console into configuring mode. Locking all HID service events from being
/// moddified
/**
* Sets the emulated controller into configuring mode
* This prevents the modification of the HID state of the emulated controller by input commands
*/
void EnableConfiguration();
/// Returns the emulated console to the normal behaivour
/// Returns the emulated controller into normal mode, allowing the modification of the HID state
void DisableConfiguration();
/// Returns true if the emulated device is on configuring mode
/// Returns true if the emulated controller is in configuring mode
bool IsConfiguring() const;
/// Reload all input devices
@@ -215,19 +217,19 @@ public:
/**
* Updates the current mapped button device
* @param ParamPackage with controller data to be mapped
* @param param ParamPackage with controller data to be mapped
*/
void SetButtonParam(std::size_t index, Common::ParamPackage param);
/**
* Updates the current mapped stick device
* @param ParamPackage with controller data to be mapped
* @param param ParamPackage with controller data to be mapped
*/
void SetStickParam(std::size_t index, Common::ParamPackage param);
/**
* Updates the current mapped motion device
* @param ParamPackage with controller data to be mapped
* @param param ParamPackage with controller data to be mapped
*/
void SetMotionParam(std::size_t index, Common::ParamPackage param);
@@ -270,13 +272,13 @@ public:
/// Returns the latest battery status from the controller
BatteryLevelState GetBattery() const;
/*
/**
* Sends a specific vibration to the output device
* @return returns true if vibration had no errors
*/
bool SetVibration(std::size_t device_index, VibrationValue vibration);
/*
/**
* Sends a small vibration to the output device
* @return returns true if SetVibration was successfull
*/
@@ -290,14 +292,14 @@ public:
/**
* Adds a callback to the list of events
* @param ConsoleUpdateCallback that will be triggered
* @param update_callback A ConsoleUpdateCallback that will be triggered
* @return an unique key corresponding to the callback index in the list
*/
int SetCallback(ControllerUpdateCallback update_callback);
/**
* Removes a callback from the list stopping any future events to this object
* @param Key corresponding to the callback index in the list
* @param key Key corresponding to the callback index in the list
*/
void DeleteCallback(int key);
@@ -310,43 +312,43 @@ private:
/**
* Updates the button status of the controller
* @param callback: A CallbackStatus containing the button status
* @param index: Button ID of the to be updated
* @param callback A CallbackStatus containing the button status
* @param index Button ID of the to be updated
*/
void SetButton(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/**
* Updates the analog stick status of the controller
* @param callback: A CallbackStatus containing the analog stick status
* @param index: stick ID of the to be updated
* @param callback A CallbackStatus containing the analog stick status
* @param index stick ID of the to be updated
*/
void SetStick(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/**
* Updates the trigger status of the controller
* @param callback: A CallbackStatus containing the trigger status
* @param index: trigger ID of the to be updated
* @param callback A CallbackStatus containing the trigger status
* @param index trigger ID of the to be updated
*/
void SetTrigger(Common::Input::CallbackStatus callback, std::size_t index, Common::UUID uuid);
/**
* Updates the motion status of the controller
* @param callback: A CallbackStatus containing gyro and accelerometer data
* @param index: motion ID of the to be updated
* @param callback A CallbackStatus containing gyro and accelerometer data
* @param index motion ID of the to be updated
*/
void SetMotion(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the battery status of the controller
* @param callback: A CallbackStatus containing the battery status
* @param index: Button ID of the to be updated
* @param callback A CallbackStatus containing the battery status
* @param index Button ID of the to be updated
*/
void SetBattery(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Triggers a callback that something has changed on the controller status
* @param type: Input type of the event to trigger
* @param is_service_update: indicates if this event should be sended to only services
* @param type Input type of the event to trigger
* @param is_service_update indicates if this event should only be sent to HID services
*/
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
@@ -357,7 +359,7 @@ private:
f32 motion_sensitivity{0.01f};
bool force_update_motion{false};
// Temporary values to avoid doing changes while the controller is on configuration mode
// Temporary values to avoid doing changes while the controller is in configuring mode
NpadStyleIndex tmp_npad_type{NpadStyleIndex::None};
bool tmp_is_connected{false};
+21 -19
View File
@@ -75,9 +75,9 @@ class EmulatedDevices {
public:
/**
* Contains all input data related to external devices that aren't necesarily a controller
* like keyboard and mouse
* This includes devices such as the keyboard or mouse
*/
EmulatedDevices();
explicit EmulatedDevices();
~EmulatedDevices();
YUZU_NON_COPYABLE(EmulatedDevices);
@@ -86,14 +86,16 @@ public:
/// Removes all callbacks created from input devices
void UnloadInput();
/// Sets the emulated console into configuring mode. Locking all HID service events from being
/// moddified
/**
* Sets the emulated devices into configuring mode
* This prevents the modification of the HID state of the emulated devices by input commands
*/
void EnableConfiguration();
/// Returns the emulated console to the normal behaivour
/// Returns the emulated devices into normal mode, allowing the modification of the HID state
void DisableConfiguration();
/// Returns true if the emulated device is on configuring mode
/// Returns true if the emulated device is in configuring mode
bool IsConfiguring() const;
/// Reload all input devices
@@ -134,14 +136,14 @@ public:
/**
* Adds a callback to the list of events
* @param InterfaceUpdateCallback that will be triggered
* @param update_callback InterfaceUpdateCallback that will be triggered
* @return an unique key corresponding to the callback index in the list
*/
int SetCallback(InterfaceUpdateCallback update_callback);
/**
* Removes a callback from the list stopping any future events to this object
* @param Key corresponding to the callback index in the list
* @param key Key corresponding to the callback index in the list
*/
void DeleteCallback(int key);
@@ -151,42 +153,42 @@ private:
/**
* Updates the touch status of the keyboard device
* @param callback: A CallbackStatus containing the key status
* @param index: key ID to be updated
* @param callback A CallbackStatus containing the key status
* @param index key ID to be updated
*/
void SetKeyboardButton(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the keyboard status of the keyboard device
* @param callback: A CallbackStatus containing the modifier key status
* @param index: modifier key ID to be updated
* @param callback A CallbackStatus containing the modifier key status
* @param index modifier key ID to be updated
*/
void SetKeyboardModifier(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the mouse button status of the mouse device
* @param callback: A CallbackStatus containing the button status
* @param index: Button ID to be updated
* @param callback A CallbackStatus containing the button status
* @param index Button ID to be updated
*/
void SetMouseButton(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the mouse wheel status of the mouse device
* @param callback: A CallbackStatus containing the wheel status
* @param index: wheel ID to be updated
* @param callback A CallbackStatus containing the wheel status
* @param index wheel ID to be updated
*/
void SetMouseAnalog(Common::Input::CallbackStatus callback, std::size_t index);
/**
* Updates the mouse position status of the mouse device
* @param callback: A CallbackStatus containing the position status
* @param index: stick ID to be updated
* @param callback A CallbackStatus containing the position status
* @param index stick ID to be updated
*/
void SetMouseStick(Common::Input::CallbackStatus callback);
/**
* Triggers a callback that something has changed on the device status
* @param Input type of the event to trigger
* @param type Input type of the event to trigger
*/
void TriggerOnChange(DeviceTriggerType type);
+26
View File
@@ -135,6 +135,32 @@ NpadIdType HIDCore::GetFirstNpadId() const {
return NpadIdType::Player1;
}
void HIDCore::EnableAllControllerConfiguration() {
player_1->EnableConfiguration();
player_2->EnableConfiguration();
player_3->EnableConfiguration();
player_4->EnableConfiguration();
player_5->EnableConfiguration();
player_6->EnableConfiguration();
player_7->EnableConfiguration();
player_8->EnableConfiguration();
other->EnableConfiguration();
handheld->EnableConfiguration();
}
void HIDCore::DisableAllControllerConfiguration() {
player_1->DisableConfiguration();
player_2->DisableConfiguration();
player_3->DisableConfiguration();
player_4->DisableConfiguration();
player_5->DisableConfiguration();
player_6->DisableConfiguration();
player_7->DisableConfiguration();
player_8->DisableConfiguration();
other->DisableConfiguration();
handheld->DisableConfiguration();
}
void HIDCore::ReloadInputDevices() {
player_1->ReloadFromSettings();
player_2->ReloadFromSettings();
+6
View File
@@ -45,6 +45,12 @@ public:
/// Returns the first connected npad id
NpadIdType GetFirstNpadId() const;
/// Sets all emulated controllers into configuring mode.
void EnableAllControllerConfiguration();
/// Sets all emulated controllers into normal mode.
void DisableAllControllerConfiguration();
/// Reloads all input devices from settings
void ReloadInputDevices();
+2
View File
@@ -63,6 +63,8 @@ enum class NpadButton : u64 {
LagonCUp = 1ULL << 32,
LagonCRight = 1ULL << 33,
LagonCDown = 1ULL << 34,
All = 0xFFFFFFFFFFFFFFFFULL,
};
DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
+12 -11
View File
@@ -21,7 +21,7 @@ namespace Core::HID {
/**
* Converts raw input data into a valid battery status.
*
* @param Supported callbacks: Analog, Battery, Trigger.
* @param callback Supported callbacks: Analog, Battery, Trigger.
* @return A valid BatteryStatus object.
*/
Common::Input::BatteryStatus TransformToBattery(const Common::Input::CallbackStatus& callback);
@@ -29,7 +29,7 @@ Common::Input::BatteryStatus TransformToBattery(const Common::Input::CallbackSta
/**
* Converts raw input data into a valid button status. Applies invert properties to the output.
*
* @param Supported callbacks: Analog, Button, Trigger.
* @param callback Supported callbacks: Analog, Button, Trigger.
* @return A valid TouchStatus object.
*/
Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatus& callback);
@@ -37,7 +37,7 @@ Common::Input::ButtonStatus TransformToButton(const Common::Input::CallbackStatu
/**
* Converts raw input data into a valid motion status.
*
* @param Supported callbacks: Motion.
* @param callback Supported callbacks: Motion.
* @return A valid TouchStatus object.
*/
Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatus& callback);
@@ -46,7 +46,7 @@ Common::Input::MotionStatus TransformToMotion(const Common::Input::CallbackStatu
* Converts raw input data into a valid stick status. Applies offset, deadzone, range and invert
* properties to the output.
*
* @param Supported callbacks: Stick.
* @param callback Supported callbacks: Stick.
* @return A valid StickStatus object.
*/
Common::Input::StickStatus TransformToStick(const Common::Input::CallbackStatus& callback);
@@ -54,7 +54,7 @@ Common::Input::StickStatus TransformToStick(const Common::Input::CallbackStatus&
/**
* Converts raw input data into a valid touch status.
*
* @param Supported callbacks: Touch.
* @param callback Supported callbacks: Touch.
* @return A valid TouchStatus object.
*/
Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus& callback);
@@ -63,7 +63,7 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
* Converts raw input data into a valid trigger status. Applies offset, deadzone, range and
* invert properties to the output. Button status uses the threshold property if necessary.
*
* @param Supported callbacks: Analog, Button, Trigger.
* @param callback Supported callbacks: Analog, Button, Trigger.
* @return A valid TriggerStatus object.
*/
Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackStatus& callback);
@@ -72,22 +72,23 @@ Common::Input::TriggerStatus TransformToTrigger(const Common::Input::CallbackSta
* Converts raw input data into a valid analog status. Applies offset, deadzone, range and
* invert properties to the output.
*
* @param Supported callbacks: Analog.
* @param callback Supported callbacks: Analog.
* @return A valid AnalogStatus object.
*/
Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatus& callback);
/**
* Converts raw analog data into a valid analog value
* @param An analog object containing raw data and properties, bool that determines if the value
* needs to be clamped between -1.0f and 1.0f.
* @param analog An analog object containing raw data and properties
* @param clamp_value determines if the value needs to be clamped between -1.0f and 1.0f.
*/
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value);
/**
* Converts raw stick data into a valid stick value
* @param Two analog objects containing raw data and properties, bool that determines if the value
* needs to be clamped into the unit circle.
* @param analog_x raw analog data and properties for the x-axis
* @param analog_y raw analog data and properties for the y-axis
* @param clamp_value bool that determines if the value needs to be clamped into the unit circle.
*/
void SanitizeStick(Common::Input::AnalogStatus& analog_x, Common::Input::AnalogStatus& analog_y,
bool clamp_value);
+8 -8
View File
@@ -20,7 +20,7 @@ InputInterpreter::InputInterpreter(Core::System& system)
InputInterpreter::~InputInterpreter() = default;
void InputInterpreter::PollInput() {
const u64 button_state = npad.GetAndResetPressState();
const auto button_state = npad.GetAndResetPressState();
previous_index = current_index;
current_index = (current_index + 1) % button_states.size();
@@ -32,30 +32,30 @@ void InputInterpreter::ResetButtonStates() {
previous_index = 0;
current_index = 0;
button_states[0] = 0xFFFFFFFFFFFFFFFF;
button_states[0] = Core::HID::NpadButton::All;
for (std::size_t i = 1; i < button_states.size(); ++i) {
button_states[i] = 0;
button_states[i] = Core::HID::NpadButton::None;
}
}
bool InputInterpreter::IsButtonPressed(Core::HID::NpadButton button) const {
return (button_states[current_index] & static_cast<u64>(button)) != 0;
return True(button_states[current_index] & button);
}
bool InputInterpreter::IsButtonPressedOnce(Core::HID::NpadButton button) const {
const bool current_press = (button_states[current_index] & static_cast<u64>(button)) != 0;
const bool previous_press = (button_states[previous_index] & static_cast<u64>(button)) != 0;
const bool current_press = True(button_states[current_index] & button);
const bool previous_press = True(button_states[previous_index] & button);
return current_press && !previous_press;
}
bool InputInterpreter::IsButtonHeld(Core::HID::NpadButton button) const {
u64 held_buttons{button_states[0]};
Core::HID::NpadButton held_buttons{button_states[0]};
for (std::size_t i = 1; i < button_states.size(); ++i) {
held_buttons &= button_states[i];
}
return (held_buttons & static_cast<u64>(button)) != 0;
return True(held_buttons & button);
}
+1 -1
View File
@@ -105,7 +105,7 @@ private:
Service::HID::Controller_NPad& npad;
/// Stores 9 consecutive button states polled from HID.
std::array<u64, 9> button_states{};
std::array<Core::HID::NpadButton, 9> button_states{};
std::size_t previous_index{};
std::size_t current_index{};
@@ -263,6 +263,10 @@ void Controller_NPad::OnInit() {
style.fullkey.Assign(1);
style.gamecube.Assign(1);
style.palma.Assign(1);
style.lark.Assign(1);
style.lucia.Assign(1);
style.lagoon.Assign(1);
style.lager.Assign(1);
hid_core.SetSupportedStyleTag(style);
}
@@ -506,7 +510,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
libnx_state.r_stick = pad_state.r_stick;
npad.system_ext_lifo.WriteNextEntry(pad_state);
press_state |= static_cast<u32>(pad_state.npad_buttons.raw);
press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
&controller.shared_memory_entry, sizeof(NpadInternalState));
@@ -631,7 +635,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
// This buffer only is updated on handheld on HW
npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
} else {
// Hanheld doesn't update this buffer on HW
// Handheld doesn't update this buffer on HW
npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
}
@@ -1145,8 +1149,8 @@ void Controller_NPad::ClearAllControllers() {
}
}
u32 Controller_NPad::GetAndResetPressState() {
return press_state.exchange(0);
Core::HID::NpadButton Controller_NPad::GetAndResetPressState() {
return static_cast<Core::HID::NpadButton>(press_state.exchange(0));
}
bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller) const {
+2 -2
View File
@@ -179,7 +179,7 @@ public:
// Logical OR for all buttons presses on all controllers
// Specifically for cheat engine and other features.
u32 GetAndResetPressState();
Core::HID::NpadButton GetAndResetPressState();
static bool IsNpadIdValid(Core::HID::NpadIdType npad_id);
static bool IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle& device_handle);
@@ -503,7 +503,7 @@ private:
NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id);
const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const;
std::atomic<u32> press_state{};
std::atomic<u64> press_state{};
std::array<NpadControllerData, 10> controller_data{};
KernelHelpers::ServiceContext& service_context;
+13 -1
View File
@@ -1883,7 +1883,7 @@ public:
{317, nullptr, "GetNpadLeftRightInterfaceType"},
{318, nullptr, "HasBattery"},
{319, nullptr, "HasLeftRightBattery"},
{321, nullptr, "GetUniquePadsFromNpad"},
{321, &HidSys::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
{322, nullptr, "GetIrSensorState"},
{323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
{324, nullptr, "GetUniquePadButtonSet"},
@@ -2054,6 +2054,18 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void GetUniquePadsFromNpad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
const s64 total_entries = 0;
LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(total_entries);
}
};
class HidTmp final : public ServiceFramework<HidTmp> {
+22 -1
View File
@@ -12,6 +12,7 @@
#include "core/hle/service/ns/errors.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/ns/pdm_qry.h"
#include "core/hle/service/ns/pl_u.h"
#include "core/hle/service/set/set.h"
@@ -570,11 +571,29 @@ IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
IFactoryResetInterface::~IFactoryResetInterface() = default;
IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface(
Core::System& system_)
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetApplicationControlData"},
{1, nullptr, "GetApplicationDesiredLanguage"},
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"},
};
// clang-format on
RegisterHandlers(functions);
}
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{7988, nullptr, "GetDynamicRightsInterface"},
{7989, nullptr, "GetReadOnlyApplicationControlDataInterface"},
{7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
{7991, nullptr, "GetReadOnlyApplicationRecordInterface"},
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
@@ -738,6 +757,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system
std::make_shared<NS_SU>(system)->InstallAsService(service_manager);
std::make_shared<NS_VM>(system)->InstallAsService(service_manager);
std::make_shared<PDM_QRY>(system)->InstallAsService(service_manager);
std::make_shared<PL_U>(system)->InstallAsService(service_manager);
}
+7
View File
@@ -74,6 +74,13 @@ public:
~IFactoryResetInterface() override;
};
class IReadOnlyApplicationControlDataInterface final
: public ServiceFramework<IReadOnlyApplicationControlDataInterface> {
public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override;
};
class NS final : public ServiceFramework<NS> {
public:
explicit NS(const char* name, Core::System& system_);
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included
#include <memory>
#include "common/logging/log.h"
#include "common/uuid.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/ns/pdm_qry.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
namespace Service::NS {
PDM_QRY::PDM_QRY(Core::System& system_) : ServiceFramework{system_, "pdm:qry"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "QueryAppletEvent"},
{1, nullptr, "QueryPlayStatistics"},
{2, nullptr, "QueryPlayStatisticsByUserAccountId"},
{3, nullptr, "QueryPlayStatisticsByNetworkServiceAccountId"},
{4, nullptr, "QueryPlayStatisticsByApplicationId"},
{5, &PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId, "QueryPlayStatisticsByApplicationIdAndUserAccountId"},
{6, nullptr, "QueryPlayStatisticsByApplicationIdAndNetworkServiceAccountId"},
{7, nullptr, "QueryLastPlayTimeV0"},
{8, nullptr, "QueryPlayEvent"},
{9, nullptr, "GetAvailablePlayEventRange"},
{10, nullptr, "QueryAccountEvent"},
{11, nullptr, "QueryAccountPlayEvent"},
{12, nullptr, "GetAvailableAccountPlayEventRange"},
{13, nullptr, "QueryApplicationPlayStatisticsForSystemV0"},
{14, nullptr, "QueryRecentlyPlayedApplication"},
{15, nullptr, "GetRecentlyPlayedApplicationUpdateEvent"},
{16, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystemV0"},
{17, nullptr, "QueryLastPlayTime"},
{18, nullptr, "QueryApplicationPlayStatisticsForSystem"},
{19, nullptr, "QueryApplicationPlayStatisticsByUserAccountIdForSystem"},
};
// clang-format on
RegisterHandlers(functions);
}
PDM_QRY::~PDM_QRY() = default;
void PDM_QRY::QueryPlayStatisticsByApplicationIdAndUserAccountId(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto unknown = rp.Pop<bool>();
rp.Pop<u8>(); // Padding
const auto application_id = rp.Pop<u64>();
const auto user_account_uid = rp.PopRaw<Common::UUID>();
// TODO(German77): Read statistics of the game
PlayStatistics statistics{
.application_id = application_id,
.total_launches = 1,
};
LOG_WARNING(Service_NS,
"(STUBBED) called. unknown={}. application_id=0x{:016X}, user_account_uid=0x{}",
unknown, application_id, user_account_uid.Format());
IPC::ResponseBuilder rb{ctx, 12};
rb.Push(ResultSuccess);
rb.PushRaw(statistics);
}
} // namespace Service::NS
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included
#pragma once
#include "core/hle/service/service.h"
namespace Service::NS {
struct PlayStatistics {
u64 application_id{};
u32 first_entry_index{};
u32 first_timestamp_user{};
u32 first_timestamp_network{};
u32 last_entry_index{};
u32 last_timestamp_user{};
u32 last_timestamp_network{};
u32 play_time_in_minutes{};
u32 total_launches{};
};
static_assert(sizeof(PlayStatistics) == 0x28, "PlayStatistics is an invalid size");
class PDM_QRY final : public ServiceFramework<PDM_QRY> {
public:
explicit PDM_QRY(Core::System& system_);
~PDM_QRY() override;
private:
void QueryPlayStatisticsByApplicationIdAndUserAccountId(Kernel::HLERequestContext& ctx);
};
} // namespace Service::NS
+1 -2
View File
@@ -19,7 +19,6 @@
namespace Core::Memory {
namespace {
constexpr auto CHEAT_ENGINE_NS = std::chrono::nanoseconds{1000000000 / 12};
constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF;
std::string_view ExtractName(std::string_view data, std::size_t start_index, char match) {
auto end_index = start_index;
@@ -61,7 +60,7 @@ u64 StandardVmCallbacks::HidKeysDown() {
applet_resource
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)
.GetAndResetPressState();
return press_state & KEYPAD_BITMASK;
return static_cast<u64>(press_state & HID::NpadButton::All);
}
void StandardVmCallbacks::DebugLog(u8 id, u64 value) {
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cstdio>
#include <fstream>
#include <vector>
#include "common/assert.h"
@@ -59,6 +61,34 @@ Codec::~Codec() {
av_buffer_unref(&av_gpu_decoder);
}
#ifdef LIBVA_FOUND
// List all the currently loaded Linux modules
static std::vector<std::string> ListLinuxKernelModules() {
using FILEPtr = std::unique_ptr<FILE, decltype(&std::fclose)>;
auto module_listing = FILEPtr{fopen("/proc/modules", "rt"), std::fclose};
std::vector<std::string> modules{};
if (!module_listing) {
LOG_WARNING(Service_NVDRV, "Could not open /proc/modules to collect available modules");
return modules;
}
char* buffer = nullptr;
size_t buf_len = 0;
while (getline(&buffer, &buf_len, module_listing.get()) != -1) {
// format for the module listing file (sysfs)
// <name> <module_size> <depended_by_count> <depended_by_names> <status> <load_address>
auto line = std::string(buffer);
// we are only interested in module names
auto name_pos = line.find_first_of(" ");
if (name_pos == std::string::npos) {
continue;
}
modules.push_back(line.erase(name_pos));
}
free(buffer);
return modules;
}
#endif
bool Codec::CreateGpuAvDevice() {
#if defined(LIBVA_FOUND)
static constexpr std::array<const char*, 3> VAAPI_DRIVERS = {
@@ -67,8 +97,16 @@ bool Codec::CreateGpuAvDevice() {
"amdgpu",
};
AVDictionary* hwdevice_options = nullptr;
const auto loaded_modules = ListLinuxKernelModules();
av_dict_set(&hwdevice_options, "connection_type", "drm", 0);
for (const auto& driver : VAAPI_DRIVERS) {
// first check if the target driver is loaded in the kernel
bool found = std::any_of(loaded_modules.begin(), loaded_modules.end(),
[&driver](const auto& module) { return module == driver; });
if (!found) {
LOG_DEBUG(Service_NVDRV, "Kernel driver {} is not loaded, trying the next one", driver);
continue;
}
av_dict_set(&hwdevice_options, "kernel_driver", driver, 0);
const int hwdevice_error = av_hwdevice_ctx_create(&av_gpu_decoder, AV_HWDEVICE_TYPE_VAAPI,
nullptr, hwdevice_options, 0);
@@ -85,11 +123,12 @@ bool Codec::CreateGpuAvDevice() {
#endif
static constexpr auto HW_CONFIG_METHOD = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX;
static constexpr std::array GPU_DECODER_TYPES{
#ifdef linux
AV_HWDEVICE_TYPE_VDPAU,
#endif
AV_HWDEVICE_TYPE_CUDA,
#ifdef _WIN32
AV_HWDEVICE_TYPE_D3D11VA,
#else
AV_HWDEVICE_TYPE_VDPAU,
#endif
};
for (const auto& type : GPU_DECODER_TYPES) {
@@ -11,13 +11,9 @@ set(SHADER_FILES
block_linear_unswizzle_2d.comp
block_linear_unswizzle_3d.comp
convert_abgr8_to_d24s8.frag
convert_b10g11r11_to_d24s8.frag
convert_d24s8_to_abgr8.frag
convert_d24s8_to_b10g11r11.frag
convert_d24s8_to_r16g16.frag
convert_depth_to_float.frag
convert_float_to_depth.frag
convert_r16g16_to_d24s8.frag
full_screen_triangle.vert
fxaa.frag
fxaa.vert
@@ -9,9 +9,10 @@ layout(binding = 0) uniform sampler2D color_texture;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
uvec4 color = uvec4(texelFetch(color_texture, coord, 0).rgba * (exp2(8) - 1.0f));
uint depth_unorm = (color.r << 16) | (color.g << 8) | color.b;
uvec4 color = uvec4(texelFetch(color_texture, coord, 0).abgr * (exp2(8) - 1.0f));
uvec4 bytes = color << uvec4(24, 16, 8, 0);
uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w;
gl_FragDepth = float(depth_unorm) / (exp2(24.0) - 1.0f);
gl_FragStencilRefARB = int(color.a);
gl_FragDepth = float(depth_stencil_unorm & 0x00FFFFFFu) / (exp2(24.0) - 1.0f);
gl_FragStencilRefARB = int(depth_stencil_unorm >> 24);
}
@@ -1,19 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#version 450
#extension GL_ARB_shader_stencil_export : require
layout(binding = 0) uniform sampler2D color_texture;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
vec4 color = texelFetch(color_texture, coord, 0).rgba;
uint depth_stencil_unorm = (uint(color.b * (exp2(10) - 1.0f)) << 22)
| (uint(color.g * (exp2(11) - 1.0f)) << 11)
| (uint(color.r * (exp2(11) - 1.0f)));
gl_FragDepth = float(depth_stencil_unorm >> 8) / (exp2(24.0) - 1.0f);
gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FF);
}
@@ -14,8 +14,10 @@ void main() {
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
color.r = float(depth >> 16) / (exp2(8) - 1.0);
color.g = float((depth >> 8) & 0x00FF) / (exp2(8) - 1.0);
color.b = float(depth & 0x00FF) / (exp2(8) - 1.0);
color.a = float(stencil) / (exp2(8) - 1.0);
highp uint depth_val =
uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0));
lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r;
highp uvec4 components =
uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu);
color.abgr = vec4(components) / (exp2(8.0) - 1.0);
}
@@ -1,21 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#version 450
layout(binding = 0) uniform sampler2D depth_tex;
layout(binding = 1) uniform isampler2D stencil_tex;
layout(location = 0) out vec4 color;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
color.b = float(depth >> 22) / (exp2(10) - 1.0);
color.g = float((depth >> 11) & 0x00FF) / (exp2(11) - 1.0);
color.r = float(depth & 0x00FF) / (exp2(11) - 1.0);
color.a = 1.0f;
}
@@ -1,21 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#version 450
layout(binding = 0) uniform sampler2D depth_tex;
layout(binding = 1) uniform isampler2D stencil_tex;
layout(location = 0) out vec4 color;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f));
uint stencil = uint(textureLod(stencil_tex, coord, 0).r);
color.r = float(depth >> 16) / (exp2(16) - 1.0);
color.g = float((depth >> 16) & 0x00FF) / (exp2(16) - 1.0);
color.b = 0.0f;
color.a = 1.0f;
}
@@ -1,18 +0,0 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#version 450
#extension GL_ARB_shader_stencil_export : require
layout(binding = 0) uniform sampler2D color_texture;
void main() {
ivec2 coord = ivec2(gl_FragCoord.xy);
vec4 color = texelFetch(color_texture, coord, 0).rgba;
uint depth_stencil_unorm = (uint(color.r * (exp2(16) - 1.0f)) << 16)
| (uint(color.g * (exp2(16) - 1.0f)) << 16);
gl_FragDepth = float(depth_stencil_unorm >> 8) / (exp2(24.0) - 1.0f);
gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FF);
}
+50 -48
View File
@@ -5,13 +5,9 @@
#include <algorithm>
#include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h"
#include "video_core/host_shaders/convert_b10g11r11_to_d24s8_frag_spv.h"
#include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h"
#include "video_core/host_shaders/convert_d24s8_to_b10g11r11_frag_spv.h"
#include "video_core/host_shaders/convert_d24s8_to_r16g16_frag_spv.h"
#include "video_core/host_shaders/convert_depth_to_float_frag_spv.h"
#include "video_core/host_shaders/convert_float_to_depth_frag_spv.h"
#include "video_core/host_shaders/convert_r16g16_to_d24s8_frag_spv.h"
#include "video_core/host_shaders/full_screen_triangle_vert_spv.h"
#include "video_core/host_shaders/vulkan_blit_color_float_frag_spv.h"
#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h"
@@ -361,11 +357,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)),
convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)),
convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)),
convert_b10g11r11_to_d24s8_frag(BuildShader(device, CONVERT_B10G11R11_TO_D24S8_FRAG_SPV)),
convert_r16g16_to_d24s8_frag(BuildShader(device, CONVERT_R16G16_TO_D24S8_FRAG_SPV)),
convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)),
convert_d24s8_to_b10g11r11_frag(BuildShader(device, CONVERT_D24S8_TO_B10G11R11_FRAG_SPV)),
convert_d24s8_to_r16g16_frag(BuildShader(device, CONVERT_D24S8_TO_R16G16_FRAG_SPV)),
linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)),
nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) {
if (device.IsExtShaderStencilExportSupported()) {
@@ -461,30 +453,11 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer,
}
void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale,
u32 down_shift) {
ImageView& src_image_view, u32 up_scale, u32 down_shift) {
ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
convert_abgr8_to_d24s8_frag, true);
Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale,
down_shift);
}
void BlitImageHelper::ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale,
u32 down_shift) {
ConvertPipelineDepthTargetEx(convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
convert_b10g11r11_to_d24s8_frag, true);
Convert(*convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale,
down_shift);
}
void BlitImageHelper::ConvertR16G16ToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale,
u32 down_shift) {
ConvertPipelineDepthTargetEx(convert_r16g16_to_d24s8_pipeline, dst_framebuffer->RenderPass(),
convert_r16g16_to_d24s8_frag, true);
Convert(*convert_r16g16_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale,
down_shift);
ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale,
down_shift);
}
void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
@@ -495,24 +468,6 @@ void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer,
down_shift);
}
void BlitImageHelper::ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale,
u32 down_shift) {
ConvertPipelineColorTargetEx(convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer->RenderPass(),
convert_d24s8_to_b10g11r11_frag, false);
ConvertDepthStencil(*convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer, src_image_view,
up_scale, down_shift);
}
void BlitImageHelper::ConvertD24S8ToR16G16(const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale,
u32 down_shift) {
ConvertPipelineColorTargetEx(convert_d24s8_to_r16g16_pipeline, dst_framebuffer->RenderPass(),
convert_d24s8_to_r16g16_frag, false);
ConvertDepthStencil(*convert_d24s8_to_r16g16_pipeline, dst_framebuffer, src_image_view,
up_scale, down_shift);
}
void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale, u32 down_shift) {
const VkPipelineLayout layout = *one_texture_pipeline_layout;
@@ -560,6 +515,53 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb
scheduler.InvalidateState();
}
void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale, u32 down_shift) {
const VkPipelineLayout layout = *one_texture_pipeline_layout;
const VkImageView src_view = src_image_view.ColorView();
const VkSampler sampler = *nearest_sampler;
const VkExtent2D extent{
.width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U),
.height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U),
};
scheduler.RequestRenderpass(dst_framebuffer);
scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift,
this](vk::CommandBuffer cmdbuf) {
const VkOffset2D offset{
.x = 0,
.y = 0,
};
const VkViewport viewport{
.x = 0.0f,
.y = 0.0f,
.width = static_cast<float>(extent.width),
.height = static_cast<float>(extent.height),
.minDepth = 0.0f,
.maxDepth = 0.0f,
};
const VkRect2D scissor{
.offset = offset,
.extent = extent,
};
const PushConstants push_constants{
.tex_scale = {viewport.width, viewport.height},
.tex_offset = {0.0f, 0.0f},
};
const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit();
UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view);
// TODO: Barriers
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set,
nullptr);
cmdbuf.SetViewport(0, viewport);
cmdbuf.SetScissor(0, scissor);
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants);
cmdbuf.Draw(3, 1, 0, 0);
});
scheduler.InvalidateState();
}
void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale, u32 down_shift) {
const VkPipelineLayout layout = *two_textures_pipeline_layout;
+4 -21
View File
@@ -56,28 +56,19 @@ public:
void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
u32 up_scale, u32 down_shift);
void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
u32 up_scale, u32 down_shift);
void ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale, u32 down_shift);
void ConvertR16G16ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
u32 up_scale, u32 down_shift);
void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
u32 up_scale, u32 down_shift);
void ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
u32 up_scale, u32 down_shift);
void ConvertD24S8ToR16G16(const Framebuffer* dst_framebuffer, ImageView& src_image_view,
u32 up_scale, u32 down_shift);
private:
void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
const ImageView& src_image_view, u32 up_scale, u32 down_shift);
void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale, u32 down_shift);
void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer,
ImageView& src_image_view, u32 up_scale, u32 down_shift);
@@ -114,11 +105,7 @@ private:
vk::ShaderModule convert_depth_to_float_frag;
vk::ShaderModule convert_float_to_depth_frag;
vk::ShaderModule convert_abgr8_to_d24s8_frag;
vk::ShaderModule convert_b10g11r11_to_d24s8_frag;
vk::ShaderModule convert_r16g16_to_d24s8_frag;
vk::ShaderModule convert_d24s8_to_abgr8_frag;
vk::ShaderModule convert_d24s8_to_b10g11r11_frag;
vk::ShaderModule convert_d24s8_to_r16g16_frag;
vk::Sampler linear_sampler;
vk::Sampler nearest_sampler;
@@ -131,11 +118,7 @@ private:
vk::Pipeline convert_d16_to_r16_pipeline;
vk::Pipeline convert_r16_to_d16_pipeline;
vk::Pipeline convert_abgr8_to_d24s8_pipeline;
vk::Pipeline convert_b10g11r11_to_d24s8_pipeline;
vk::Pipeline convert_r16g16_to_d24s8_pipeline;
vk::Pipeline convert_d24s8_to_abgr8_pipeline;
vk::Pipeline convert_d24s8_to_b10g11r11_pipeline;
vk::Pipeline convert_d24s8_to_r16g16_pipeline;
};
} // namespace Vulkan
@@ -775,8 +775,18 @@ StagingBufferRef TextureCacheRuntime::DownloadStagingBuffer(size_t size) {
bool TextureCacheRuntime::ShouldReinterpret(Image& dst, Image& src) {
if (VideoCore::Surface::GetFormatType(dst.info.format) ==
VideoCore::Surface::SurfaceType::DepthStencil) {
return !device.IsExtShaderStencilExportSupported();
VideoCore::Surface::SurfaceType::DepthStencil &&
!device.IsExtShaderStencilExportSupported()) {
return true;
}
if (VideoCore::Surface::GetFormatType(src.info.format) ==
VideoCore::Surface::SurfaceType::DepthStencil &&
!device.IsExtShaderStencilExportSupported()) {
return true;
}
if (dst.info.format == PixelFormat::D32_FLOAT_S8_UINT ||
src.info.format == PixelFormat::D32_FLOAT_S8_UINT) {
return true;
}
return false;
}
@@ -1058,21 +1068,10 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
}
break;
case PixelFormat::A8B8G8R8_UNORM:
case PixelFormat::B8G8R8A8_UNORM:
if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) {
return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift);
}
break;
case PixelFormat::B10G11R11_FLOAT:
if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) {
return blit_image_helper.ConvertD24S8ToB10G11R11(dst, src_view, up_scale, down_shift);
}
break;
case PixelFormat::R16G16_UNORM:
if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) {
return blit_image_helper.ConvertD24S8ToR16G16(dst, src_view, up_scale, down_shift);
}
break;
case PixelFormat::R32_FLOAT:
if (src_view.format == PixelFormat::D32_FLOAT) {
return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift);
@@ -1084,16 +1083,7 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im
}
break;
case PixelFormat::S8_UINT_D24_UNORM:
if (src_view.format == PixelFormat::A8B8G8R8_UNORM ||
src_view.format == PixelFormat::B8G8R8A8_UNORM) {
return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift);
}
if (src_view.format == PixelFormat::B10G11R11_FLOAT) {
return blit_image_helper.ConvertB10G11R11ToD24S8(dst, src_view, up_scale, down_shift);
}
if (src_view.format == PixelFormat::R16G16_UNORM) {
return blit_image_helper.ConvertR16G16ToD24S8(dst, src_view, up_scale, down_shift);
}
return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift);
break;
case PixelFormat::D32_FLOAT:
if (src_view.format == PixelFormat::R32_FLOAT) {
@@ -1590,6 +1580,14 @@ VkImageView ImageView::StencilView() {
return *stencil_view;
}
VkImageView ImageView::ColorView() {
if (color_view) {
return *color_view;
}
color_view = MakeView(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
return *color_view;
}
VkImageView ImageView::StorageView(Shader::TextureType texture_type,
Shader::ImageFormat image_format) {
if (image_format == Shader::ImageFormat::Typeless) {
@@ -184,6 +184,8 @@ public:
[[nodiscard]] VkImageView StencilView();
[[nodiscard]] VkImageView ColorView();
[[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type,
Shader::ImageFormat image_format);
@@ -224,6 +226,7 @@ private:
std::unique_ptr<StorageViews> storage_views;
vk::ImageView depth_view;
vk::ImageView stencil_view;
vk::ImageView color_view;
VkImage image_handle = VK_NULL_HANDLE;
VkImageView render_target = VK_NULL_HANDLE;
VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT;
+74 -22
View File
@@ -472,7 +472,7 @@ template <class P>
void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy) {
const BlitImages images = GetBlitImages(dst, src);
const BlitImages images = GetBlitImages(dst, src, copy);
const ImageId dst_id = images.dst_id;
const ImageId src_id = images.src_id;
@@ -762,12 +762,15 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
const bool broken_views =
runtime.HasBrokenTextureViewFormats() || True(options & RelaxedOptions::ForceBrokenViews);
const bool native_bgr = runtime.HasNativeBgr();
ImageId image_id;
const bool flexible_formats = True(options & RelaxedOptions::Format);
ImageId image_id{};
boost::container::small_vector<ImageId, 1> image_ids;
const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) {
if (True(existing_image.flags & ImageFlagBits::Remapped)) {
return false;
}
if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) {
if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear)
[[unlikely]] {
const bool strict_size = False(options & RelaxedOptions::Size) &&
True(existing_image.flags & ImageFlagBits::Strong);
const ImageInfo& existing = existing_image.info;
@@ -776,17 +779,27 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
IsPitchLinearSameSize(existing, info, strict_size) &&
IsViewCompatible(existing.format, info.format, broken_views, native_bgr)) {
image_id = existing_image_id;
return true;
image_ids.push_back(existing_image_id);
return !flexible_formats && existing.format == info.format;
}
} else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views,
native_bgr)) {
image_id = existing_image_id;
return true;
image_ids.push_back(existing_image_id);
return !flexible_formats && existing_image.info.format == info.format;
}
return false;
};
ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda);
return image_id;
if (image_ids.size() <= 1) [[likely]] {
return image_id;
}
auto image_ids_compare = [this](ImageId a, ImageId b) {
auto& image_a = slot_images[a];
auto& image_b = slot_images[b];
return image_a.modification_tick < image_b.modification_tick;
};
return *std::ranges::max_element(image_ids, image_ids_compare);
}
template <class P>
@@ -1078,32 +1091,58 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
template <class P>
typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages(
const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src) {
static constexpr auto FIND_OPTIONS = RelaxedOptions::Format | RelaxedOptions::Samples;
const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy) {
static constexpr auto FIND_OPTIONS = RelaxedOptions::Samples;
const GPUVAddr dst_addr = dst.Address();
const GPUVAddr src_addr = src.Address();
ImageInfo dst_info(dst);
ImageInfo src_info(src);
const bool can_be_depth_blit =
dst_info.format == src_info.format && copy.filter == Tegra::Engines::Fermi2D::Filter::Point;
ImageId dst_id;
ImageId src_id;
RelaxedOptions try_options = FIND_OPTIONS;
if (can_be_depth_blit) {
try_options |= RelaxedOptions::Format;
}
do {
has_deleted_images = false;
dst_id = FindImage(dst_info, dst_addr, FIND_OPTIONS);
src_id = FindImage(src_info, src_addr, FIND_OPTIONS);
const ImageBase* const dst_image = dst_id ? &slot_images[dst_id] : nullptr;
src_id = FindImage(src_info, src_addr, try_options);
dst_id = FindImage(dst_info, dst_addr, try_options);
const ImageBase* const src_image = src_id ? &slot_images[src_id] : nullptr;
DeduceBlitImages(dst_info, src_info, dst_image, src_image);
if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) {
continue;
if (src_image && src_image->info.num_samples > 1) {
RelaxedOptions find_options{FIND_OPTIONS | RelaxedOptions::ForceBrokenViews};
src_id = FindOrInsertImage(src_info, src_addr, find_options);
dst_id = FindOrInsertImage(dst_info, dst_addr, find_options);
if (has_deleted_images) {
continue;
}
break;
}
RelaxedOptions find_options{};
if (src_info.num_samples > 1) {
// it's a resolve, we must enforce the same format.
find_options = RelaxedOptions::ForceBrokenViews;
if (can_be_depth_blit) {
const ImageBase* const dst_image = src_id ? &slot_images[src_id] : nullptr;
DeduceBlitImages(dst_info, src_info, dst_image, src_image);
if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) {
continue;
}
}
if (!src_id) {
src_id = InsertImage(src_info, src_addr, RelaxedOptions{});
}
if (!dst_id) {
dst_id = InsertImage(dst_info, dst_addr, RelaxedOptions{});
}
src_id = FindOrInsertImage(src_info, src_addr, find_options);
dst_id = FindOrInsertImage(dst_info, dst_addr, find_options);
} while (has_deleted_images);
if (GetFormatType(dst_info.format) != SurfaceType::ColorTexture) {
// Make sure the images are depth and/or stencil textures.
do {
has_deleted_images = false;
src_id = FindOrInsertImage(src_info, src_addr, RelaxedOptions{});
dst_id = FindOrInsertImage(dst_info, dst_addr, RelaxedOptions{});
} while (has_deleted_images);
}
return BlitImages{
.dst_id = dst_id,
.src_id = src_id,
@@ -1160,7 +1199,14 @@ template <class P>
ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr,
bool is_clear) {
const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{};
const ImageId image_id = FindOrInsertImage(info, gpu_addr, options);
ImageId image_id{};
bool delete_state = has_deleted_images;
do {
has_deleted_images = false;
image_id = FindOrInsertImage(info, gpu_addr, options);
delete_state |= has_deleted_images;
} while (has_deleted_images);
has_deleted_images = delete_state;
if (!image_id) {
return NULL_IMAGE_VIEW_ID;
}
@@ -1783,7 +1829,13 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag
const SubresourceExtent src_extent{.levels = 1, .layers = 1};
const SubresourceRange dst_range{.base = dst_base, .extent = dst_extent};
const SubresourceRange src_range{.base = src_base, .extent = src_extent};
const ImageViewInfo dst_view_info(ImageViewType::e2D, dst.info.format, dst_range);
PixelFormat dst_format = dst.info.format;
if (GetFormatType(src.info.format) == SurfaceType::DepthStencil &&
GetFormatType(dst_format) == SurfaceType::ColorTexture &&
BytesPerBlock(dst_format) == 4) {
dst_format = PixelFormat::A8B8G8R8_UNORM;
}
const ImageViewInfo dst_view_info(ImageViewType::e2D, dst_format, dst_range);
const ImageViewInfo src_view_info(ImageViewType::e2D, src.info.format, src_range);
const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info);
Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id];
@@ -252,7 +252,8 @@ private:
/// Return a blit image pair from the given guest blit parameters
[[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst,
const Tegra::Engines::Fermi2D::Surface& src);
const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy);
/// Find or create a sampler from a guest descriptor sampler
[[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
+3 -17
View File
@@ -1151,28 +1151,15 @@ bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr
void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst,
const ImageBase* src) {
bool is_resolve = false;
const auto original_src_format = src_info.format;
const auto original_dst_format = dst_info.format;
if (src) {
if (GetFormatType(src->info.format) != SurfaceType::ColorTexture) {
src_info.format = src->info.format;
}
is_resolve = src->info.num_samples > 1;
src_info.num_samples = src->info.num_samples;
src_info.size = src->info.size;
if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) {
src_info.format = src->info.format;
}
if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) {
dst_info.format = dst->info.format;
}
if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) {
if (dst) {
if (GetFormatType(dst->info.format) == SurfaceType::ColorTexture) {
src_info.format = original_src_format;
}
} else {
dst_info.format = src->info.format;
}
dst_info.format = src->info.format;
}
if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) {
if (src) {
@@ -1183,7 +1170,6 @@ void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase*
src_info.format = dst->info.format;
}
}
ASSERT(!is_resolve || dst_info.format == src_info.format);
}
u32 MapSizeBytes(const ImageBase& image) {
+5 -5
View File
@@ -139,7 +139,6 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
DisableUnsupportedPlayers();
for (std::size_t player_index = 0; player_index < NUM_PLAYERS; ++player_index) {
system.HIDCore().GetEmulatedControllerByIndex(player_index)->EnableConfiguration();
SetEmulatedControllers(player_index);
}
@@ -218,7 +217,9 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
resize(0, 0);
}
QtControllerSelectorDialog::~QtControllerSelectorDialog() = default;
QtControllerSelectorDialog::~QtControllerSelectorDialog() {
system.HIDCore().DisableAllControllerConfiguration();
}
int QtControllerSelectorDialog::exec() {
if (parameters_met && parameters.enable_single_mode) {
@@ -234,12 +235,11 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
for (std::size_t player_index = 0; player_index < NUM_PLAYERS; ++player_index) {
system.HIDCore().GetEmulatedControllerByIndex(player_index)->DisableConfiguration();
}
}
void QtControllerSelectorDialog::LoadConfiguration() {
system.HIDCore().EnableAllControllerConfiguration();
const auto* handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(index);
+2
View File
@@ -508,6 +508,7 @@ void Config::ReadDebuggingValues() {
ReadBasicSetting(Settings::values.extended_logging);
ReadBasicSetting(Settings::values.use_debug_asserts);
ReadBasicSetting(Settings::values.use_auto_stub);
ReadBasicSetting(Settings::values.enable_all_controllers);
qt_config->endGroup();
}
@@ -1051,6 +1052,7 @@ void Config::SaveDebuggingValues() {
WriteBasicSetting(Settings::values.quest_flag);
WriteBasicSetting(Settings::values.use_debug_asserts);
WriteBasicSetting(Settings::values.disable_macro_jit);
WriteBasicSetting(Settings::values.enable_all_controllers);
qt_config->endGroup();
}
@@ -42,6 +42,7 @@ void ConfigureDebug::SetConfiguration() {
ui->quest_flag->setChecked(Settings::values.quest_flag.GetValue());
ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts.GetValue());
ui->use_auto_stub->setChecked(Settings::values.use_auto_stub.GetValue());
ui->enable_all_controllers->setChecked(Settings::values.enable_all_controllers.GetValue());
ui->enable_graphics_debugging->setEnabled(runtime_lock);
ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue());
ui->enable_shader_feedback->setEnabled(runtime_lock);
@@ -67,6 +68,7 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.quest_flag = ui->quest_flag->isChecked();
Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
Settings::values.use_auto_stub = ui->use_auto_stub->isChecked();
Settings::values.enable_all_controllers = ui->enable_all_controllers->isChecked();
Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
@@ -198,6 +198,13 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="enable_all_controllers">
<property name="text">
<string>Enable all Controller Types</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@@ -246,15 +246,15 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
if (player_index == 0) {
auto* emulated_controller_p1 =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* emulated_controller_hanheld =
auto* emulated_controller_handheld =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
emulated_controller_p1->SaveCurrentConfig();
emulated_controller_p1->EnableConfiguration();
emulated_controller_hanheld->SaveCurrentConfig();
emulated_controller_hanheld->EnableConfiguration();
if (emulated_controller_hanheld->IsConnected(true)) {
emulated_controller_handheld->SaveCurrentConfig();
emulated_controller_handheld->EnableConfiguration();
if (emulated_controller_handheld->IsConnected(true)) {
emulated_controller_p1->Disconnect();
emulated_controller = emulated_controller_hanheld;
emulated_controller = emulated_controller_handheld;
} else {
emulated_controller = emulated_controller_p1;
}
@@ -590,19 +590,19 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
if (player_index == 0) {
auto* emulated_controller_p1 =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* emulated_controller_hanheld =
auto* emulated_controller_handheld =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
bool is_connected = emulated_controller->IsConnected(true);
emulated_controller_p1->SetNpadStyleIndex(type);
emulated_controller_hanheld->SetNpadStyleIndex(type);
emulated_controller_handheld->SetNpadStyleIndex(type);
if (is_connected) {
if (type == Core::HID::NpadStyleIndex::Handheld) {
emulated_controller_p1->Disconnect();
emulated_controller_hanheld->Connect();
emulated_controller = emulated_controller_hanheld;
emulated_controller_handheld->Connect();
emulated_controller = emulated_controller_handheld;
} else {
emulated_controller_hanheld->Disconnect();
emulated_controller_handheld->Disconnect();
emulated_controller_p1->Connect();
emulated_controller = emulated_controller_p1;
}
@@ -650,10 +650,10 @@ ConfigureInputPlayer::~ConfigureInputPlayer() {
if (player_index == 0) {
auto* emulated_controller_p1 =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* emulated_controller_hanheld =
auto* emulated_controller_handheld =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
emulated_controller_p1->DisableConfiguration();
emulated_controller_hanheld->DisableConfiguration();
emulated_controller_handheld->DisableConfiguration();
} else {
emulated_controller->DisableConfiguration();
}
@@ -663,14 +663,14 @@ void ConfigureInputPlayer::ApplyConfiguration() {
if (player_index == 0) {
auto* emulated_controller_p1 =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* emulated_controller_hanheld =
auto* emulated_controller_handheld =
hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
emulated_controller_p1->DisableConfiguration();
emulated_controller_p1->SaveCurrentConfig();
emulated_controller_p1->EnableConfiguration();
emulated_controller_hanheld->DisableConfiguration();
emulated_controller_hanheld->SaveCurrentConfig();
emulated_controller_hanheld->EnableConfiguration();
emulated_controller_handheld->DisableConfiguration();
emulated_controller_handheld->SaveCurrentConfig();
emulated_controller_handheld->EnableConfiguration();
return;
}
emulated_controller->DisableConfiguration();
@@ -947,6 +947,40 @@ void ConfigureInputPlayer::SetConnectableControllers() {
Core::HID::NpadStyleIndex::GameCube);
ui->comboControllerType->addItem(tr("GameCube Controller"));
}
// Disable all unsupported controllers
if (!Settings::values.enable_all_controllers) {
return;
}
if (enable_all || npad_style_set.palma == 1) {
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
Core::HID::NpadStyleIndex::Pokeball);
ui->comboControllerType->addItem(tr("Poke Ball Plus"));
}
if (enable_all || npad_style_set.lark == 1) {
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
Core::HID::NpadStyleIndex::NES);
ui->comboControllerType->addItem(tr("NES Controller"));
}
if (enable_all || npad_style_set.lucia == 1) {
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
Core::HID::NpadStyleIndex::SNES);
ui->comboControllerType->addItem(tr("SNES Controller"));
}
if (enable_all || npad_style_set.lagoon == 1) {
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
Core::HID::NpadStyleIndex::N64);
ui->comboControllerType->addItem(tr("N64 Controller"));
}
if (enable_all || npad_style_set.lager == 1) {
index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
Core::HID::NpadStyleIndex::SegaGenesis);
ui->comboControllerType->addItem(tr("Sega Genesis"));
}
};
if (!is_powered_on) {
+28 -26
View File
@@ -3479,36 +3479,38 @@ void GMainWindow::filterBarSetChecked(bool state) {
}
void GMainWindow::UpdateUITheme() {
const QString default_icons = QStringLiteral("default");
const QString& current_theme = UISettings::values.theme;
const bool is_default_theme = current_theme == QString::fromUtf8(UISettings::themes[0].second);
const QString default_theme = QStringLiteral("default");
QString current_theme = UISettings::values.theme;
QStringList theme_paths(default_theme_paths);
if (is_default_theme || current_theme.isEmpty()) {
const QString theme_uri(QStringLiteral(":default/style.qss"));
QFile f(theme_uri);
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
setStyleSheet(ts.readAll());
} else {
qApp->setStyleSheet({});
setStyleSheet({});
}
QIcon::setThemeName(default_icons);
} else {
const QString theme_uri(QLatin1Char{':'} + current_theme + QStringLiteral("/style.qss"));
QFile f(theme_uri);
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
}
QIcon::setThemeName(current_theme);
if (current_theme.isEmpty()) {
current_theme = default_theme;
}
if (current_theme != default_theme) {
QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
QFile f(theme_uri);
if (!f.open(QFile::ReadOnly | QFile::Text)) {
LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme",
UISettings::values.theme.toStdString());
current_theme = default_theme;
}
}
QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
QFile f(theme_uri);
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style \"{}\", stylesheet file not found",
UISettings::values.theme.toStdString());
qApp->setStyleSheet({});
setStyleSheet({});
}
QIcon::setThemeName(current_theme);
QIcon::setThemeSearchPaths(theme_paths);
}
+2 -2
View File
@@ -7,8 +7,8 @@
namespace UISettings {
const Themes themes{{
{"Light", "default"},
{"Light Colorful", "colorful"},
{"Default", "default"},
{"Default Colorful", "colorful"},
{"Dark", "qdarkstyle"},
{"Dark Colorful", "colorful_dark"},
{"Midnight Blue", "qdarkstyle_midnight_blue"},