From b37854dccc189d4394c64dc5b5c4a8bf61b6e4a2 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 31 Oct 2021 18:43:26 +0100 Subject: [PATCH] early-access version 2173 --- README.md | 2 +- .../hle/service/nvdrv/devices/nvhost_ctrl.cpp | 20 +++++++++++++++++++ .../hle/service/nvdrv/devices/nvhost_ctrl.h | 8 +++++--- .../frontend/ir/basic_block.h | 14 +++++++++++++ .../frontend/ir/microinstruction.cpp | 11 ++++++++++ src/shader_recompiler/frontend/ir/value.h | 3 +++ .../frontend/maxwell/translate_program.cpp | 2 ++ .../ir_opt/ssa_rewrite_pass.cpp | 7 +++++++ 8 files changed, 63 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 826a6a2bd..b4503282c 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2172. +This is the source code for early-access 2173. ## Legal Notice diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 08147be94..a2f174d74 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +// SPDX-License-Identifier: MPL-2.0 +// Copyright 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) +// Copyright 2019-2020 Ryujinx Team and Contributors + #include #include @@ -38,6 +42,8 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector& return IocCtrlEventRegister(input, output); case 0x20: return IocCtrlEventUnregister(input, output); + case 0x21: + return IocCtrlFreeEventBatch(input, output); } break; default: @@ -212,4 +218,18 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector& input, std::v return NvResult::Success; } +NvResult nvhost_ctrl::IocCtrlFreeEventBatch(const std::vector& input, std::vector& output) { + IocCtrlFreeEventBatchParams params{}; + std::memcpy(¶ms, input.data(), sizeof(params)); + + LOG_DEBUG(Service_NVDRV, "called, bit_mask={}", params.bit_mask); + + for (u32 event_id = 0; event_id < MaxNvEvents; ++event_id) { + if (params.bit_mask & (1ULL << event_id)) { + events_interface.UnregisterEvent(event_id); + } + } + + return NvResult::Success; +} } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index cdf03887d..69a1bc93c 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h @@ -119,16 +119,18 @@ private: static_assert(sizeof(IocCtrlEventUnregisterParams) == 4, "IocCtrlEventUnregisterParams is incorrect size"); - struct IocCtrlEventKill { - u64_le user_events{}; + struct IocCtrlFreeEventBatchParams { + u64_le bit_mask{}; }; - static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); + static_assert(sizeof(IocCtrlFreeEventBatchParams) == 8, + "IocCtrlFreeEventBatchParams is incorrect size"); NvResult NvOsGetConfigU32(const std::vector& input, std::vector& output); NvResult IocCtrlEventWait(const std::vector& input, std::vector& output, bool is_async); NvResult IocCtrlEventRegister(const std::vector& input, std::vector& output); NvResult IocCtrlEventUnregister(const std::vector& input, std::vector& output); NvResult IocCtrlClearEventWait(const std::vector& input, std::vector& output); + NvResult IocCtrlFreeEventBatch(const std::vector& input, std::vector& output); EventInterface& events_interface; SyncpointManager& syncpoint_manager; diff --git a/src/shader_recompiler/frontend/ir/basic_block.h b/src/shader_recompiler/frontend/ir/basic_block.h index a56155ef4..fbfe98266 100755 --- a/src/shader_recompiler/frontend/ir/basic_block.h +++ b/src/shader_recompiler/frontend/ir/basic_block.h @@ -155,6 +155,17 @@ public: return instructions.crend(); } + // Set the order of the block, it can be set pre order, the user decides + void SetOrder(u32 new_order) { + order = new_order; + } + + // Get the order of the block. + // The higher, the closer is the block to the end. + [[nodiscard]] u32 GetOrder() const { + return order; + } + private: /// Memory pool for instruction list ObjectPool* inst_pool; @@ -174,6 +185,9 @@ private: /// Intrusively stored host definition of this block. u32 definition{}; + + /// Order of the block. + u32 order{}; }; using BlockList = std::vector; diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 25795c179..9d61141de 100755 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -6,6 +6,7 @@ #include #include "shader_recompiler/exception.h" +#include "shader_recompiler/frontend/ir/basic_block.h" #include "shader_recompiler/frontend/ir/type.h" #include "shader_recompiler/frontend/ir/value.h" @@ -302,6 +303,16 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) { phi_args.emplace_back(predecessor, value); } +void Inst::OrderPhiArgs() { + if (op != Opcode::Phi) { + throw LogicError("{} is not a Phi instruction", op); + } + std::sort(phi_args.begin(), phi_args.end(), + [](const std::pair& a, const std::pair& b) { + return a.first->GetOrder() < b.first->GetOrder(); + }); +} + void Inst::Invalidate() { ClearArgs(); ReplaceOpcode(Opcode::Void); diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h index 8cddde231..c5efdad73 100755 --- a/src/shader_recompiler/frontend/ir/value.h +++ b/src/shader_recompiler/frontend/ir/value.h @@ -182,6 +182,9 @@ public: /// Add phi operand to a phi instruction. void AddPhiOperand(Block* predecessor, const Value& value); + /// Orders the Phi arguments. + void OrderPhiArgs(); + void Invalidate(); void ClearArgs(); diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 5caf225a6..267ebe4af 100755 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp @@ -27,9 +27,11 @@ IR::BlockList GenerateBlocks(const IR::AbstractSyntaxList& syntax_list) { } IR::BlockList blocks; blocks.reserve(num_syntax_blocks); + u32 order_index{}; for (const auto& node : syntax_list) { if (node.type == IR::AbstractSyntaxNode::Type::Block) { blocks.push_back(node.data.block); + blocks.back()->SetOrder(order_index++); } } return blocks; diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 53145fb5e..5545f8197 100755 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp @@ -378,6 +378,13 @@ void SsaRewritePass(IR::Program& program) { for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { VisitBlock(pass, *block); } + for (auto block = program.post_order_blocks.rbegin(); block != end; ++block) { + for (IR::Inst& inst : (*block)->Instructions()) { + if (inst.GetOpcode() == IR::Opcode::Phi) { + inst.OrderPhiArgs(); + } + } + } } } // namespace Shader::Optimization