early-access version 3581

main
pineappleEA 2023-05-11 22:19:53 +02:00
parent 5f158ebb5e
commit ba2ffe4391
12 changed files with 100 additions and 71 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3580. This is the source code for early-access 3581.
## Legal Notice ## Legal Notice

View File

@ -188,8 +188,6 @@ void AudioRenderer::ThreadFunc() {
max_time = std::min(command_buffer.time_limit, max_time); max_time = std::min(command_buffer.time_limit, max_time);
command_list_processor.SetProcessTimeMax(max_time); command_list_processor.SetProcessTimeMax(max_time);
streams[index]->WaitFreeSpace();
// Process the command list // Process the command list
{ {
MICROPROFILE_SCOPE(Audio_Renderer); MICROPROFILE_SCOPE(Audio_Renderer);

View File

@ -15,9 +15,14 @@ MICROPROFILE_DEFINE(Audio_RenderSystemManager, "Audio", "Render System Manager",
MP_RGB(60, 19, 97)); MP_RGB(60, 19, 97));
namespace AudioCore::AudioRenderer { namespace AudioCore::AudioRenderer {
constexpr std::chrono::nanoseconds RENDER_TIME{5'000'000UL};
SystemManager::SystemManager(Core::System& core_) SystemManager::SystemManager(Core::System& core_)
: core{core_}, adsp{core.AudioCore().GetADSP()}, mailbox{adsp.GetRenderMailbox()} {} : core{core_}, adsp{core.AudioCore().GetADSP()}, mailbox{adsp.GetRenderMailbox()},
thread_event{Core::Timing::CreateEvent(
"AudioRendererSystemManager", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) {
return ThreadFunc2(time);
})} {}
SystemManager::~SystemManager() { SystemManager::~SystemManager() {
Stop(); Stop();
@ -27,7 +32,9 @@ bool SystemManager::InitializeUnsafe() {
if (!active) { if (!active) {
if (adsp.Start()) { if (adsp.Start()) {
active = true; active = true;
thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(); }); thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); });
core.CoreTiming().ScheduleLoopingEvent(std::chrono::nanoseconds(0), RENDER_TIME,
thread_event);
} }
} }
@ -38,9 +45,13 @@ void SystemManager::Stop() {
if (!active) { if (!active) {
return; return;
} }
core.CoreTiming().UnscheduleEvent(thread_event, {});
active = false; active = false;
update.store(true); {
update.notify_all(); std::scoped_lock l{cv_mutex};
do_update = false;
}
thread.request_stop();
thread.join(); thread.join();
adsp.Stop(); adsp.Stop();
} }
@ -85,12 +96,12 @@ bool SystemManager::Remove(System& system_) {
return true; return true;
} }
void SystemManager::ThreadFunc() { void SystemManager::ThreadFunc(std::stop_token stop_token) {
static constexpr char name[]{"AudioRenderSystemManager"}; static constexpr char name[]{"AudioRenderSystemManager"};
MicroProfileOnThreadCreate(name); MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name); Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High); Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
while (active) { while (active && !stop_token.stop_requested()) {
{ {
std::scoped_lock l{mutex1}; std::scoped_lock l{mutex1};
@ -103,7 +114,20 @@ void SystemManager::ThreadFunc() {
adsp.Signal(); adsp.Signal();
adsp.Wait(); adsp.Wait();
std::unique_lock l{cv_mutex};
Common::CondvarWait(update_cv, l, stop_token, [this]() { return do_update; });
do_update = false;
} }
} }
std::optional<std::chrono::nanoseconds> SystemManager::ThreadFunc2(s64 time) {
{
std::scoped_lock l{cv_mutex};
do_update = true;
}
update_cv.notify_all();
return std::nullopt;
}
} // namespace AudioCore::AudioRenderer } // namespace AudioCore::AudioRenderer

View File

@ -66,13 +66,12 @@ private:
/** /**
* Main thread responsible for command generation. * Main thread responsible for command generation.
*/ */
void ThreadFunc(); void ThreadFunc(std::stop_token stop_token);
enum class StreamState { /**
Filling, * Signalling core timing thread to run ThreadFunc.
Steady, */
Draining, std::optional<std::chrono::nanoseconds> ThreadFunc2(s64 time);
};
/// Core system /// Core system
Core::System& core; Core::System& core;
@ -90,8 +89,12 @@ private:
ADSP::ADSP& adsp; ADSP::ADSP& adsp;
/// AudioRenderer mailbox for communication /// AudioRenderer mailbox for communication
ADSP::AudioRenderer_Mailbox* mailbox{}; ADSP::AudioRenderer_Mailbox* mailbox{};
/// Core timing event to signal main thread
std::shared_ptr<Core::Timing::EventType> thread_event;
/// Atomic for main thread to wait on /// Atomic for main thread to wait on
std::atomic<bool> update{}; std::mutex cv_mutex{};
bool do_update{};
std::condition_variable_any update_cv{};
}; };
} // namespace AudioCore::AudioRenderer } // namespace AudioCore::AudioRenderer

View File

@ -268,10 +268,4 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
return std::min<u64>(exp_played_sample_count, max_played_sample_count) + TargetSampleCount * 3; return std::min<u64>(exp_played_sample_count, max_played_sample_count) + TargetSampleCount * 3;
} }
void SinkStream::WaitFreeSpace() {
std::unique_lock lk{release_mutex};
release_cv.wait(
lk, [this]() { return queued_buffers < max_queue_size || system.IsShuttingDown(); });
}
} // namespace AudioCore::Sink } // namespace AudioCore::Sink

View File

@ -207,11 +207,6 @@ public:
*/ */
u64 GetExpectedPlayedSampleCount(); u64 GetExpectedPlayedSampleCount();
/**
* Waits for free space in the sample ring buffer
*/
void WaitFreeSpace();
protected: protected:
/// Core system /// Core system
Core::System& system; Core::System& system;

View File

@ -339,9 +339,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
if (ctx.profile.support_vertex_instance_id) { if (ctx.profile.support_vertex_instance_id) {
return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_id)); return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_id));
} else { } else {
const Id index{ctx.OpLoad(ctx.U32[1], ctx.vertex_index)}; return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.vertex_index));
const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)};
return ctx.OpBitcast(ctx.F32[1], ctx.OpISub(ctx.U32[1], index, base));
} }
case IR::Attribute::BaseInstance: case IR::Attribute::BaseInstance:
return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance)); return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance));
@ -386,9 +384,7 @@ Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id) {
if (ctx.profile.support_vertex_instance_id) { if (ctx.profile.support_vertex_instance_id) {
return ctx.OpLoad(ctx.U32[1], ctx.vertex_id); return ctx.OpLoad(ctx.U32[1], ctx.vertex_id);
} else { } else {
const Id index{ctx.OpLoad(ctx.U32[1], ctx.vertex_index)}; return ctx.OpLoad(ctx.U32[1], ctx.vertex_index);
const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)};
return ctx.OpISub(ctx.U32[1], index, base);
} }
case IR::Attribute::BaseInstance: case IR::Attribute::BaseInstance:
return ctx.OpLoad(ctx.U32[1], ctx.base_instance); return ctx.OpLoad(ctx.U32[1], ctx.base_instance);

View File

@ -102,12 +102,7 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
} }
IR::F32 value{v.ir.CompositeExtract(sample, element)}; IR::F32 value{v.ir.CompositeExtract(sample, element)};
if (element < 2) { if (element < 2) {
IR::U32 casted_value; IR::U32 casted_value = v.ir.ConvertFToU(32, value);
if (element == 0) {
casted_value = v.ir.ConvertFToU(32, value);
} else {
casted_value = v.ir.ConvertFToS(16, value);
}
v.X(dest_reg, v.ir.ShiftLeftLogical(casted_value, v.ir.Imm32(8))); v.X(dest_reg, v.ir.ShiftLeftLogical(casted_value, v.ir.Imm32(8)));
} else { } else {
v.F(dest_reg, value); v.F(dest_reg, value);

View File

@ -48,7 +48,9 @@ ConfigureHotkeys::ConfigureHotkeys(Core::HID::HIDCore& hid_core, QWidget* parent
connect(poll_timer.get(), &QTimer::timeout, [this] { connect(poll_timer.get(), &QTimer::timeout, [this] {
const auto buttons = controller->GetNpadButtons(); const auto buttons = controller->GetNpadButtons();
if (buttons.raw != Core::HID::NpadButton::None) { const auto home_pressed = controller->GetHomeButtons().home != 0;
const auto capture_pressed = controller->GetCaptureButtons().capture != 0;
if (home_pressed || capture_pressed) {
SetPollingResult(buttons.raw, false); SetPollingResult(buttons.raw, false);
return; return;
} }
@ -154,8 +156,10 @@ void ConfigureHotkeys::ConfigureController(QModelIndex index) {
model->setData(index, previous_key); model->setData(index, previous_key);
return; return;
} }
const auto home_pressed = this->controller->GetHomeButtons().home != 0;
const QString button_string = tr("Home+%1").arg(GetButtonName(button)); const auto capture_pressed = this->controller->GetCaptureButtons().capture != 0;
const QString button_string =
GetButtonCombinationName(button, home_pressed, capture_pressed);
const auto [key_sequence_used, used_action] = IsUsedControllerKey(button_string); const auto [key_sequence_used, used_action] = IsUsedControllerKey(button_string);
@ -174,72 +178,83 @@ void ConfigureHotkeys::ConfigureController(QModelIndex index) {
poll_timer->start(200); // Check for new inputs every 200ms poll_timer->start(200); // Check for new inputs every 200ms
// We need to disable configuration to be able to read npad buttons // We need to disable configuration to be able to read npad buttons
controller->DisableConfiguration(); controller->DisableConfiguration();
controller->DisableSystemButtons();
} }
void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool cancel) { void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool cancel) {
timeout_timer->stop(); timeout_timer->stop();
poll_timer->stop(); poll_timer->stop();
(*input_setter)(button, cancel);
// Re-Enable configuration // Re-Enable configuration
controller->EnableConfiguration(); controller->EnableConfiguration();
controller->EnableSystemButtons();
(*input_setter)(button, cancel);
input_setter = std::nullopt; input_setter = std::nullopt;
} }
QString ConfigureHotkeys::GetButtonName(Core::HID::NpadButton button) const { QString ConfigureHotkeys::GetButtonCombinationName(Core::HID::NpadButton button,
const bool home = false,
const bool capture = false) const {
Core::HID::NpadButtonState state{button}; Core::HID::NpadButtonState state{button};
QString button_combination;
if (home) {
button_combination.append(QStringLiteral("Home+"));
}
if (capture) {
button_combination.append(QStringLiteral("Screenshot+"));
}
if (state.a) { if (state.a) {
return QStringLiteral("A"); button_combination.append(QStringLiteral("A+"));
} }
if (state.b) { if (state.b) {
return QStringLiteral("B"); button_combination.append(QStringLiteral("B+"));
} }
if (state.x) { if (state.x) {
return QStringLiteral("X"); button_combination.append(QStringLiteral("X+"));
} }
if (state.y) { if (state.y) {
return QStringLiteral("Y"); button_combination.append(QStringLiteral("Y+"));
} }
if (state.l || state.right_sl || state.left_sl) { if (state.l || state.right_sl || state.left_sl) {
return QStringLiteral("L"); button_combination.append(QStringLiteral("L+"));
} }
if (state.r || state.right_sr || state.left_sr) { if (state.r || state.right_sr || state.left_sr) {
return QStringLiteral("R"); button_combination.append(QStringLiteral("R+"));
} }
if (state.zl) { if (state.zl) {
return QStringLiteral("ZL"); button_combination.append(QStringLiteral("ZL+"));
} }
if (state.zr) { if (state.zr) {
return QStringLiteral("ZR"); button_combination.append(QStringLiteral("ZR+"));
} }
if (state.left) { if (state.left) {
return QStringLiteral("Dpad_Left"); button_combination.append(QStringLiteral("Dpad_Left+"));
} }
if (state.right) { if (state.right) {
return QStringLiteral("Dpad_Right"); button_combination.append(QStringLiteral("Dpad_Right+"));
} }
if (state.up) { if (state.up) {
return QStringLiteral("Dpad_Up"); button_combination.append(QStringLiteral("Dpad_Up+"));
} }
if (state.down) { if (state.down) {
return QStringLiteral("Dpad_Down"); button_combination.append(QStringLiteral("Dpad_Down+"));
} }
if (state.stick_l) { if (state.stick_l) {
return QStringLiteral("Left_Stick"); button_combination.append(QStringLiteral("Left_Stick+"));
} }
if (state.stick_r) { if (state.stick_r) {
return QStringLiteral("Right_Stick"); button_combination.append(QStringLiteral("Right_Stick+"));
} }
if (state.minus) { if (state.minus) {
return QStringLiteral("Minus"); button_combination.append(QStringLiteral("Minus+"));
} }
if (state.plus) { if (state.plus) {
return QStringLiteral("Plus"); button_combination.append(QStringLiteral("Plus+"));
}
if (button_combination.isEmpty()) {
return tr("Invalid");
} else {
button_combination.chop(1);
return button_combination;
} }
return tr("Invalid");
} }
std::pair<bool, QString> ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const { std::pair<bool, QString> ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {

View File

@ -59,7 +59,7 @@ private:
QStandardItemModel* model; QStandardItemModel* model;
void SetPollingResult(Core::HID::NpadButton button, bool cancel); void SetPollingResult(Core::HID::NpadButton button, bool cancel);
QString GetButtonName(Core::HID::NpadButton button) const; QString GetButtonCombinationName(Core::HID::NpadButton button, bool home, bool capture) const;
Core::HID::EmulatedController* controller; Core::HID::EmulatedController* controller;
std::unique_ptr<QTimer> timeout_timer; std::unique_ptr<QTimer> timeout_timer;
std::unique_ptr<QTimer> poll_timer; std::unique_ptr<QTimer> poll_timer;

View File

@ -1164,7 +1164,8 @@ void GMainWindow::InitializeRecentFileMenuActions() {
UpdateRecentFiles(); UpdateRecentFiles();
} }
void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name) { void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name,
const bool tas_allowed) {
static const QString main_window = QStringLiteral("Main Window"); static const QString main_window = QStringLiteral("Main Window");
action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name)); action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name));
action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name)); action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name));
@ -1176,7 +1177,14 @@ void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name
const auto* controller_hotkey = const auto* controller_hotkey =
hotkey_registry.GetControllerHotkey(main_window, action_name, controller); hotkey_registry.GetControllerHotkey(main_window, action_name, controller);
connect( connect(
controller_hotkey, &ControllerShortcut::Activated, this, [action] { action->trigger(); }, controller_hotkey, &ControllerShortcut::Activated, this,
[action, tas_allowed, this] {
auto [tas_status, current_tas_frame, total_tas_frames] =
input_subsystem->GetTas()->GetStatus();
if (tas_allowed || tas_status == InputCommon::TasInput::TasState::Stopped) {
action->trigger();
}
},
Qt::QueuedConnection); Qt::QueuedConnection);
} }
@ -1193,9 +1201,9 @@ void GMainWindow::InitializeHotkeys() {
LinkActionShortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar")); LinkActionShortcut(ui->action_Show_Status_Bar, QStringLiteral("Toggle Status Bar"));
LinkActionShortcut(ui->action_Fullscreen, QStringLiteral("Fullscreen")); LinkActionShortcut(ui->action_Fullscreen, QStringLiteral("Fullscreen"));
LinkActionShortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot")); LinkActionShortcut(ui->action_Capture_Screenshot, QStringLiteral("Capture Screenshot"));
LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop")); LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop"), true);
LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record")); LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record"), true);
LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset")); LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset"), true);
static const QString main_window = QStringLiteral("Main Window"); static const QString main_window = QStringLiteral("Main Window");
const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) {

View File

@ -214,7 +214,8 @@ public slots:
private: private:
/// Updates an action's shortcut and text to reflect an updated hotkey from the hotkey registry. /// Updates an action's shortcut and text to reflect an updated hotkey from the hotkey registry.
void LinkActionShortcut(QAction* action, const QString& action_name); void LinkActionShortcut(QAction* action, const QString& action_name,
const bool tas_allowed = false);
void RegisterMetaTypes(); void RegisterMetaTypes();