summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/am/am.cpp15
-rw-r--r--src/core/hle/service/am/am.h1
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp10
-rwxr-xr-xsrc/input_common/analog_from_button.cpp14
-rw-r--r--src/video_core/shader/decode/arithmetic.cpp33
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp94
6 files changed, 105 insertions, 62 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index cc978713b..d1bf13c89 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -607,7 +607,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system,
{40, nullptr, "GetCradleFwVersion"},
{50, nullptr, "IsVrModeEnabled"},
{51, nullptr, "SetVrModeEnabled"},
- {52, nullptr, "SwitchLcdBacklight"},
+ {52, &ICommonStateGetter::SetLcdBacklighOffEnabled, "SetLcdBacklighOffEnabled"},
{53, nullptr, "BeginVrModeEx"},
{54, nullptr, "EndVrModeEx"},
{55, nullptr, "IsInControllerFirmwareUpdateSection"},
@@ -636,7 +636,6 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
-
rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode
}
@@ -660,6 +659,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
return;
}
+
rb.Push(RESULT_SUCCESS);
rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
}
@@ -672,6 +672,17 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
rb.Push(static_cast<u8>(FocusState::InFocus));
}
+void ICommonStateGetter::SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto is_lcd_backlight_off_enabled = rp.Pop<bool>();
+
+ LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}",
+ is_lcd_backlight_off_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+}
+
void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 0b9a4332d..0843de781 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -182,6 +182,7 @@ private:
void GetOperationMode(Kernel::HLERequestContext& ctx);
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
void GetBootMode(Kernel::HLERequestContext& ctx);
+ void SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx);
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 15c09f04c..c1e32b28c 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -287,13 +287,13 @@ void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
Input::AnalogDirection::DOWN));
- pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
- ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
- pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
- ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
pad_state.r_stick_right.Assign(
analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
- ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
+ ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
+ pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
+ ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
+ pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
+ ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
pad_state.r_stick_down.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
diff --git a/src/input_common/analog_from_button.cpp b/src/input_common/analog_from_button.cpp
index e1a260762..6cabdaa3c 100755
--- a/src/input_common/analog_from_button.cpp
+++ b/src/input_common/analog_from_button.cpp
@@ -34,6 +34,20 @@ public:
y * coef * (x == 0 ? 1.0f : SQRT_HALF));
}
+ bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {
+ switch (direction) {
+ case Input::AnalogDirection::RIGHT:
+ return right->GetStatus();
+ case Input::AnalogDirection::LEFT:
+ return left->GetStatus();
+ case Input::AnalogDirection::UP:
+ return up->GetStatus();
+ case Input::AnalogDirection::DOWN:
+ return down->GetStatus();
+ }
+ return false;
+ }
+
private:
Button up;
Button down;
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp
index 90240c765..478394682 100644
--- a/src/video_core/shader/decode/arithmetic.cpp
+++ b/src/video_core/shader/decode/arithmetic.cpp
@@ -53,29 +53,24 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) {
op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b);
- // TODO(Rodrigo): Should precise be used when there's a postfactor?
- Node value = Operation(OperationCode::FMul, PRECISE, op_a, op_b);
+ static constexpr std::array FmulPostFactor = {
+ 1.000f, // None
+ 0.500f, // Divide 2
+ 0.250f, // Divide 4
+ 0.125f, // Divide 8
+ 8.000f, // Mul 8
+ 4.000f, // Mul 4
+ 2.000f, // Mul 2
+ };
if (instr.fmul.postfactor != 0) {
- auto postfactor = static_cast<s32>(instr.fmul.postfactor);
-
- // Postfactor encoded as 3-bit 1's complement in instruction, interpreted with below
- // logic.
- if (postfactor >= 4) {
- postfactor = 7 - postfactor;
- } else {
- postfactor = 0 - postfactor;
- }
-
- if (postfactor > 0) {
- value = Operation(OperationCode::FMul, NO_PRECISE, value,
- Immediate(static_cast<f32>(1 << postfactor)));
- } else {
- value = Operation(OperationCode::FDiv, NO_PRECISE, value,
- Immediate(static_cast<f32>(1 << -postfactor)));
- }
+ op_a = Operation(OperationCode::FMul, NO_PRECISE, op_a,
+ Immediate(FmulPostFactor[instr.fmul.postfactor]));
}
+ // TODO(Rodrigo): Should precise be used when there's a postfactor?
+ Node value = Operation(OperationCode::FMul, PRECISE, op_a, op_b);
+
value = GetSaturatedFloat(value, instr.alu.saturate_d);
SetInternalFlagsFromFloat(bb, value, instr.generates_cc);
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 21366869d..2fe787d6f 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -293,44 +293,66 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Node op_b, Node op_c,
Node imm_lut, bool sets_cc) {
- constexpr u32 lop_iterations = 32;
- const Node one = Immediate(1);
- const Node two = Immediate(2);
-
- Node value;
- for (u32 i = 0; i < lop_iterations; ++i) {
- const Node shift_amount = Immediate(i);
-
- const Node a = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_c, shift_amount);
- const Node pack_0 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, one);
-
- const Node b = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_b, shift_amount);
- const Node c = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, b, one);
- const Node pack_1 = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, c, one);
-
- const Node d = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_a, shift_amount);
- const Node e = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, d, one);
- const Node pack_2 = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, e, two);
-
- const Node pack_01 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, pack_0, pack_1);
- const Node pack_012 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, pack_01, pack_2);
-
- const Node shifted_bit =
- Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, imm_lut, pack_012);
- const Node bit = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, shifted_bit, one);
-
- const Node right =
- Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, bit, shift_amount);
-
- if (i > 0) {
- value = Operation(OperationCode::IBitwiseOr, NO_PRECISE, value, right);
- } else {
- value = right;
+ const Node lop3_fast = [&](const Node na, const Node nb, const Node nc, const Node ttbl) {
+ Node value = Immediate(0);
+ const ImmediateNode imm = std::get<ImmediateNode>(*ttbl);
+ if (imm.GetValue() & 0x01) {
+ const Node a = Operation(OperationCode::IBitwiseNot, na);
+ const Node b = Operation(OperationCode::IBitwiseNot, nb);
+ const Node c = Operation(OperationCode::IBitwiseNot, nc);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, b);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
}
- }
+ if (imm.GetValue() & 0x02) {
+ const Node a = Operation(OperationCode::IBitwiseNot, na);
+ const Node b = Operation(OperationCode::IBitwiseNot, nb);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, b);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x04) {
+ const Node a = Operation(OperationCode::IBitwiseNot, na);
+ const Node c = Operation(OperationCode::IBitwiseNot, nc);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, nb);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x08) {
+ const Node a = Operation(OperationCode::IBitwiseNot, na);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, nb);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x10) {
+ const Node b = Operation(OperationCode::IBitwiseNot, nb);
+ const Node c = Operation(OperationCode::IBitwiseNot, nc);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, b);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x20) {
+ const Node b = Operation(OperationCode::IBitwiseNot, nb);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, b);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x40) {
+ const Node c = Operation(OperationCode::IBitwiseNot, nc);
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, nb);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ if (imm.GetValue() & 0x80) {
+ Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, nb);
+ r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
+ value = Operation(OperationCode::IBitwiseOr, value, r);
+ }
+ return value;
+ }(op_a, op_b, op_c, imm_lut);
- SetInternalFlagsFromInteger(bb, value, sets_cc);
- SetRegister(bb, dest, value);
+ SetInternalFlagsFromInteger(bb, lop3_fast, sets_cc);
+ SetRegister(bb, dest, lop3_fast);
}
} // namespace VideoCommon::Shader