summaryrefslogtreecommitdiff
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,
607 {40, nullptr, "GetCradleFwVersion"}, 607 {40, nullptr, "GetCradleFwVersion"},
608 {50, nullptr, "IsVrModeEnabled"}, 608 {50, nullptr, "IsVrModeEnabled"},
609 {51, nullptr, "SetVrModeEnabled"}, 609 {51, nullptr, "SetVrModeEnabled"},
610 {52, nullptr, "SwitchLcdBacklight"}, 610 {52, &ICommonStateGetter::SetLcdBacklighOffEnabled, "SetLcdBacklighOffEnabled"},
611 {53, nullptr, "BeginVrModeEx"}, 611 {53, nullptr, "BeginVrModeEx"},
612 {54, nullptr, "EndVrModeEx"}, 612 {54, nullptr, "EndVrModeEx"},
613 {55, nullptr, "IsInControllerFirmwareUpdateSection"}, 613 {55, nullptr, "IsInControllerFirmwareUpdateSection"},
@@ -636,7 +636,6 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
636 636
637 IPC::ResponseBuilder rb{ctx, 3}; 637 IPC::ResponseBuilder rb{ctx, 3};
638 rb.Push(RESULT_SUCCESS); 638 rb.Push(RESULT_SUCCESS);
639
640 rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode 639 rb.Push<u8>(static_cast<u8>(Service::PM::SystemBootMode::Normal)); // Normal boot mode
641} 640}
642 641
@@ -660,6 +659,7 @@ void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
660 rb.PushEnum<AppletMessageQueue::AppletMessage>(message); 659 rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
661 return; 660 return;
662 } 661 }
662
663 rb.Push(RESULT_SUCCESS); 663 rb.Push(RESULT_SUCCESS);
664 rb.PushEnum<AppletMessageQueue::AppletMessage>(message); 664 rb.PushEnum<AppletMessageQueue::AppletMessage>(message);
665} 665}
@@ -672,6 +672,17 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
672 rb.Push(static_cast<u8>(FocusState::InFocus)); 672 rb.Push(static_cast<u8>(FocusState::InFocus));
673} 673}
674 674
675void ICommonStateGetter::SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx) {
676 IPC::RequestParser rp{ctx};
677 const auto is_lcd_backlight_off_enabled = rp.Pop<bool>();
678
679 LOG_WARNING(Service_AM, "(STUBBED) called. is_lcd_backlight_off_enabled={}",
680 is_lcd_backlight_off_enabled);
681
682 IPC::ResponseBuilder rb{ctx, 2};
683 rb.Push(RESULT_SUCCESS);
684}
685
675void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { 686void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
676 LOG_DEBUG(Service_AM, "called"); 687 LOG_DEBUG(Service_AM, "called");
677 688
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:
182 void GetOperationMode(Kernel::HLERequestContext& ctx); 182 void GetOperationMode(Kernel::HLERequestContext& ctx);
183 void GetPerformanceMode(Kernel::HLERequestContext& ctx); 183 void GetPerformanceMode(Kernel::HLERequestContext& ctx);
184 void GetBootMode(Kernel::HLERequestContext& ctx); 184 void GetBootMode(Kernel::HLERequestContext& ctx);
185 void SetLcdBacklighOffEnabled(Kernel::HLERequestContext& ctx);
185 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); 186 void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
186 void SetCpuBoostMode(Kernel::HLERequestContext& ctx); 187 void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
187 188
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) {
287 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus( 287 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetAnalogDirectionStatus(
288 Input::AnalogDirection::DOWN)); 288 Input::AnalogDirection::DOWN));
289 289
290 pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
291 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
292 pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
293 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
294 pad_state.r_stick_right.Assign( 290 pad_state.r_stick_right.Assign(
295 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 291 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
296 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP)); 292 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
293 pad_state.r_stick_left.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
294 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
295 pad_state.r_stick_up.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
296 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
297 pad_state.r_stick_down.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)] 297 pad_state.r_stick_down.Assign(analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
298 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN)); 298 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
299 299
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:
34 y * coef * (x == 0 ? 1.0f : SQRT_HALF)); 34 y * coef * (x == 0 ? 1.0f : SQRT_HALF));
35 } 35 }
36 36
37 bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {
38 switch (direction) {
39 case Input::AnalogDirection::RIGHT:
40 return right->GetStatus();
41 case Input::AnalogDirection::LEFT:
42 return left->GetStatus();
43 case Input::AnalogDirection::UP:
44 return up->GetStatus();
45 case Input::AnalogDirection::DOWN:
46 return down->GetStatus();
47 }
48 return false;
49 }
50
37private: 51private:
38 Button up; 52 Button up;
39 Button down; 53 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) {
53 53
54 op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b); 54 op_b = GetOperandAbsNegFloat(op_b, false, instr.fmul.negate_b);
55 55
56 // TODO(Rodrigo): Should precise be used when there's a postfactor? 56 static constexpr std::array FmulPostFactor = {
57 Node value = Operation(OperationCode::FMul, PRECISE, op_a, op_b); 57 1.000f, // None
58 0.500f, // Divide 2
59 0.250f, // Divide 4
60 0.125f, // Divide 8
61 8.000f, // Mul 8
62 4.000f, // Mul 4
63 2.000f, // Mul 2
64 };
58 65
59 if (instr.fmul.postfactor != 0) { 66 if (instr.fmul.postfactor != 0) {
60 auto postfactor = static_cast<s32>(instr.fmul.postfactor); 67 op_a = Operation(OperationCode::FMul, NO_PRECISE, op_a,
61 68 Immediate(FmulPostFactor[instr.fmul.postfactor]));
62 // Postfactor encoded as 3-bit 1's complement in instruction, interpreted with below
63 // logic.
64 if (postfactor >= 4) {
65 postfactor = 7 - postfactor;
66 } else {
67 postfactor = 0 - postfactor;
68 }
69
70 if (postfactor > 0) {
71 value = Operation(OperationCode::FMul, NO_PRECISE, value,
72 Immediate(static_cast<f32>(1 << postfactor)));
73 } else {
74 value = Operation(OperationCode::FDiv, NO_PRECISE, value,
75 Immediate(static_cast<f32>(1 << -postfactor)));
76 }
77 } 69 }
78 70
71 // TODO(Rodrigo): Should precise be used when there's a postfactor?
72 Node value = Operation(OperationCode::FMul, PRECISE, op_a, op_b);
73
79 value = GetSaturatedFloat(value, instr.alu.saturate_d); 74 value = GetSaturatedFloat(value, instr.alu.saturate_d);
80 75
81 SetInternalFlagsFromFloat(bb, value, instr.generates_cc); 76 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) {
293 293
294void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Node op_b, Node op_c, 294void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Node op_b, Node op_c,
295 Node imm_lut, bool sets_cc) { 295 Node imm_lut, bool sets_cc) {
296 constexpr u32 lop_iterations = 32; 296 const Node lop3_fast = [&](const Node na, const Node nb, const Node nc, const Node ttbl) {
297 const Node one = Immediate(1); 297 Node value = Immediate(0);
298 const Node two = Immediate(2); 298 const ImmediateNode imm = std::get<ImmediateNode>(*ttbl);
299 299 if (imm.GetValue() & 0x01) {
300 Node value; 300 const Node a = Operation(OperationCode::IBitwiseNot, na);
301 for (u32 i = 0; i < lop_iterations; ++i) { 301 const Node b = Operation(OperationCode::IBitwiseNot, nb);
302 const Node shift_amount = Immediate(i); 302 const Node c = Operation(OperationCode::IBitwiseNot, nc);
303 303 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, b);
304 const Node a = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_c, shift_amount); 304 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
305 const Node pack_0 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, one); 305 value = Operation(OperationCode::IBitwiseOr, value, r);
306
307 const Node b = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_b, shift_amount);
308 const Node c = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, b, one);
309 const Node pack_1 = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, c, one);
310
311 const Node d = Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, op_a, shift_amount);
312 const Node e = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, d, one);
313 const Node pack_2 = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, e, two);
314
315 const Node pack_01 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, pack_0, pack_1);
316 const Node pack_012 = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, pack_01, pack_2);
317
318 const Node shifted_bit =
319 Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, imm_lut, pack_012);
320 const Node bit = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, shifted_bit, one);
321
322 const Node right =
323 Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, bit, shift_amount);
324
325 if (i > 0) {
326 value = Operation(OperationCode::IBitwiseOr, NO_PRECISE, value, right);
327 } else {
328 value = right;
329 } 306 }
330 } 307 if (imm.GetValue() & 0x02) {
308 const Node a = Operation(OperationCode::IBitwiseNot, na);
309 const Node b = Operation(OperationCode::IBitwiseNot, nb);
310 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, b);
311 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
312 value = Operation(OperationCode::IBitwiseOr, value, r);
313 }
314 if (imm.GetValue() & 0x04) {
315 const Node a = Operation(OperationCode::IBitwiseNot, na);
316 const Node c = Operation(OperationCode::IBitwiseNot, nc);
317 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, nb);
318 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
319 value = Operation(OperationCode::IBitwiseOr, value, r);
320 }
321 if (imm.GetValue() & 0x08) {
322 const Node a = Operation(OperationCode::IBitwiseNot, na);
323 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, a, nb);
324 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
325 value = Operation(OperationCode::IBitwiseOr, value, r);
326 }
327 if (imm.GetValue() & 0x10) {
328 const Node b = Operation(OperationCode::IBitwiseNot, nb);
329 const Node c = Operation(OperationCode::IBitwiseNot, nc);
330 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, b);
331 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
332 value = Operation(OperationCode::IBitwiseOr, value, r);
333 }
334 if (imm.GetValue() & 0x20) {
335 const Node b = Operation(OperationCode::IBitwiseNot, nb);
336 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, b);
337 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
338 value = Operation(OperationCode::IBitwiseOr, value, r);
339 }
340 if (imm.GetValue() & 0x40) {
341 const Node c = Operation(OperationCode::IBitwiseNot, nc);
342 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, nb);
343 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, c);
344 value = Operation(OperationCode::IBitwiseOr, value, r);
345 }
346 if (imm.GetValue() & 0x80) {
347 Node r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, na, nb);
348 r = Operation(OperationCode::IBitwiseAnd, NO_PRECISE, r, nc);
349 value = Operation(OperationCode::IBitwiseOr, value, r);
350 }
351 return value;
352 }(op_a, op_b, op_c, imm_lut);
331 353
332 SetInternalFlagsFromInteger(bb, value, sets_cc); 354 SetInternalFlagsFromInteger(bb, lop3_fast, sets_cc);
333 SetRegister(bb, dest, value); 355 SetRegister(bb, dest, lop3_fast);
334} 356}
335 357
336} // namespace VideoCommon::Shader 358} // namespace VideoCommon::Shader