diff options
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 10 | ||||
| -rwxr-xr-x | src/input_common/analog_from_button.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic.cpp | 33 | ||||
| -rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 94 |
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 | ||
| 675 | void 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 | |||
| 675 | void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) { | 686 | void 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 | |||
| 37 | private: | 51 | private: |
| 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 | ||
| 294 | void ShaderIR::WriteLop3Instruction(NodeBlock& bb, Register dest, Node op_a, Node op_b, Node op_c, | 294 | void 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 |