early-access version 3971

This commit is contained in:
pineappleEA 2023-11-11 17:36:08 +01:00
parent b1b49d9789
commit 44caed8bb2
18 changed files with 88 additions and 62 deletions

View file

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

View file

@ -203,6 +203,8 @@ const char* TranslateCategory(Category category) {
case Category::Ui:
case Category::UiGeneral:
return "UI";
case Category::UiAudio:
return "UiAudio";
case Category::UiLayout:
return "UiLayout";
case Category::UiGameList:

View file

@ -153,7 +153,7 @@ struct Values {
true,
true};
Setting<bool, false> audio_muted{
linkage, false, "audio_muted", Category::Audio, Specialization::Default, false, true};
linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true};
Setting<bool, false> dump_audio_commands{
linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};

View file

@ -32,6 +32,7 @@ enum class Category : u32 {
AddOns,
Controls,
Ui,
UiAudio,
UiGeneral,
UiLayout,
UiGameList,

View file

@ -68,10 +68,6 @@ public:
}
};
void InvalidateEntireInstructionCache(Core::System& system) {
system.InvalidateCpuInstructionCaches();
}
template <typename AddressType>
void InvalidateInstructionCache(Core::System& system, AddressType addr, u64 size) {
system.InvalidateCpuInstructionCacheRange(GetInteger(addr), size);
@ -435,9 +431,6 @@ void KPageTableBase::Finalize() {
m_mapped_ipc_server_memory);
}
// Invalidate the entire instruction cache.
InvalidateEntireInstructionCache(m_system);
// Close the backing page table, as the destructor is not called for guest objects.
m_impl.reset();
}

View file

@ -3,16 +3,18 @@
#include <queue>
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/irsensor/clustering_processor.h"
namespace Service::IRS {
ClusteringProcessor::ClusteringProcessor(Core::HID::HIDCore& hid_core_,
ClusteringProcessor::ClusteringProcessor(Core::System& system_,
Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index)
: device{device_format} {
npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index);
: device{device_format}, system{system_} {
npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor;
device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
@ -83,7 +85,7 @@ void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType ty
}
next_state.sampling_number = camera_data.sample;
next_state.timestamp = next_state.timestamp + 131;
next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
shared_memory->clustering_lifo.WriteNextEntry(next_state);

View file

@ -8,6 +8,10 @@
#include "core/hle/service/hid/irs_ring_lifo.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
namespace Core {
class System;
}
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
@ -15,8 +19,7 @@ class EmulatedController;
namespace Service::IRS {
class ClusteringProcessor final : public ProcessorBase {
public:
explicit ClusteringProcessor(Core::HID::HIDCore& hid_core_,
Core::IrSensor::DeviceFormat& device_format,
explicit ClusteringProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index);
~ClusteringProcessor() override;
@ -106,5 +109,7 @@ private:
Core::IrSensor::DeviceFormat& device;
Core::HID::EmulatedController* npad_device;
int callback_key{};
Core::System& system;
};
} // namespace Service::IRS

View file

@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/irsensor/moment_processor.h"
@ -10,11 +12,10 @@ static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Siz
static constexpr std::size_t ImageWidth = 40;
static constexpr std::size_t ImageHeight = 30;
MomentProcessor::MomentProcessor(Core::HID::HIDCore& hid_core_,
Core::IrSensor::DeviceFormat& device_format,
MomentProcessor::MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index)
: device(device_format) {
npad_device = hid_core_.GetEmulatedControllerByIndex(npad_index);
: device(device_format), system{system_} {
npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index);
device.mode = Core::IrSensor::IrSensorMode::MomentProcessor;
device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected;
@ -69,7 +70,7 @@ void MomentProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type)
}
next_state.sampling_number = camera_data.sample;
next_state.timestamp = next_state.timestamp + 131;
next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count();
next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low;
shared_memory->moment_lifo.WriteNextEntry(next_state);

View file

@ -9,11 +9,19 @@
#include "core/hle/service/hid/irs_ring_lifo.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
namespace Core {
class System;
}
namespace Core::HID {
class EmulatedController;
} // namespace Core::HID
namespace Service::IRS {
class MomentProcessor final : public ProcessorBase {
public:
explicit MomentProcessor(Core::HID::HIDCore& hid_core_,
Core::IrSensor::DeviceFormat& device_format, std::size_t npad_index);
explicit MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format,
std::size_t npad_index);
~MomentProcessor() override;
// Called when the processor is initialized
@ -76,6 +84,8 @@ private:
Core::IrSensor::DeviceFormat& device;
Core::HID::EmulatedController* npad_device;
int callback_key{};
Core::System& system;
};
} // namespace Service::IRS

View file

@ -1,8 +1,10 @@
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <cstring>
#include <mutex>
#include <span>
#include "common/assert.h"
@ -10,6 +12,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/page_table.h"
#include "common/scope_exit.h"
#include "common/settings.h"
#include "common/swap.h"
#include "core/core.h"
@ -318,7 +321,7 @@ struct Memory::Impl {
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
if constexpr (!UNSAFE) {
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
}
std::memcpy(host_ptr, src_buffer, copy_amount);
},
@ -351,7 +354,7 @@ struct Memory::Impl {
},
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount);
HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
std::memset(host_ptr, 0, copy_amount);
},
[](const std::size_t copy_amount) {});
@ -420,7 +423,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc cvac: Store to point of coherency
// CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
}
@ -430,7 +433,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache
// CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size);
HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
};
return PerformCacheOperation(dest_addr, size, on_rasterizer);
}
@ -767,7 +770,18 @@ struct Memory::Impl {
}
void HandleRasterizerWrite(VAddr address, size_t size) {
const size_t core = system.GetCurrentHostThreadID();
constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
const size_t core = std::min(system.GetCurrentHostThreadID(),
sys_core); // any other calls threads go to syscore.
// Guard on sys_core;
if (core == sys_core) [[unlikely]] {
sys_core_guard.lock();
}
SCOPE_EXIT({
if (core == sys_core) [[unlikely]] {
sys_core_guard.unlock();
}
});
auto& current_area = rasterizer_write_areas[core];
VAddr subaddress = address >> YUZU_PAGEBITS;
bool do_collection = current_area.last_address == subaddress;
@ -799,6 +813,7 @@ struct Memory::Impl {
rasterizer_read_areas{};
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
std::mutex sys_core_guard;
};
Memory::Memory(Core::System& system_) : system{system_} {

View file

@ -86,10 +86,7 @@ public:
uncommitted_operations.emplace_back(std::move(func));
}
pending_operations.emplace_back(std::move(uncommitted_operations));
{
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
QueueFence(new_fence);
}
QueueFence(new_fence);
if (!delay_fence) {
func();
}

View file

@ -132,16 +132,12 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
const bool use_accelerated =
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
const bool is_srgb = use_accelerated && screen_info.is_srgb;
RenderScreenshot(*framebuffer, use_accelerated);
{
std::scoped_lock lock{rasterizer.LockCaches()};
RenderScreenshot(*framebuffer, use_accelerated);
Frame* frame = present_manager.GetRenderFrame();
blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
scheduler.Flush(*frame->render_ready);
present_manager.Present(frame);
}
Frame* frame = present_manager.GetRenderFrame();
blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
scheduler.Flush(*frame->render_ready);
present_manager.Present(frame);
gpu.RendererFrameEndNotify();
rasterizer.TickFrame();

View file

@ -199,7 +199,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
if (!pipeline) {
return;
}
std::scoped_lock lock{LockCaches()};
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
// update engine as channel may be different.
pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
@ -710,7 +710,6 @@ void RasterizerVulkan::TiledCacheBarrier() {
}
void RasterizerVulkan::FlushCommands() {
std::scoped_lock lock{LockCaches()};
if (draw_counter == 0) {
return;
}
@ -808,7 +807,6 @@ void RasterizerVulkan::FlushWork() {
if ((++draw_counter & 7) != 7) {
return;
}
std::scoped_lock lock{LockCaches()};
if (draw_counter < DRAWS_TO_DISPATCH) {
// Send recorded tasks to the worker thread
scheduler.DispatchWork();
@ -1507,7 +1505,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
CreateChannel(channel);
{
std::scoped_lock lock{LockCaches()};
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.CreateChannel(channel);
buffer_cache.CreateChannel(channel);
}
@ -1520,7 +1518,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
const s32 channel_id = channel.bind_id;
BindToChannel(channel_id);
{
std::scoped_lock lock{LockCaches()};
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.BindToChannel(channel_id);
buffer_cache.BindToChannel(channel_id);
}
@ -1533,7 +1531,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
EraseChannel(channel_id);
{
std::scoped_lock lock{LockCaches()};
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.EraseChannel(channel_id);
buffer_cache.EraseChannel(channel_id);
}

View file

@ -133,10 +133,6 @@ public:
void ReleaseChannel(s32 channel_id) override;
std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
}
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;

View file

@ -360,6 +360,7 @@ void Config::ReadAudioValues() {
qt_config->beginGroup(QStringLiteral("Audio"));
ReadCategory(Settings::Category::Audio);
ReadCategory(Settings::Category::UiAudio);
qt_config->endGroup();
}
@ -900,6 +901,7 @@ void Config::SaveAudioValues() {
qt_config->beginGroup(QStringLiteral("Audio"));
WriteCategory(Settings::Category::Audio);
WriteCategory(Settings::Category::UiAudio);
qt_config->endGroup();
}

View file

@ -38,17 +38,21 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
std::map<u32, QWidget*> hold;
auto push = [&](Settings::Category category) {
auto push_settings = [&](Settings::Category category) {
for (auto* setting : Settings::values.linkage.by_category[category]) {
settings.push_back(setting);
}
};
auto push_ui_settings = [&](Settings::Category category) {
for (auto* setting : UISettings::values.linkage.by_category[category]) {
settings.push_back(setting);
}
};
push(Settings::Category::Audio);
push(Settings::Category::SystemAudio);
push_settings(Settings::Category::Audio);
push_settings(Settings::Category::SystemAudio);
push_ui_settings(Settings::Category::UiAudio);
for (auto* setting : settings) {
auto* widget = builder.BuildWidget(setting, apply_funcs);

View file

@ -1065,12 +1065,6 @@ void GMainWindow::InitializeWidgets() {
volume_slider->setObjectName(QStringLiteral("volume_slider"));
volume_slider->setMaximum(200);
volume_slider->setPageStep(5);
connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
Settings::values.audio_muted = false;
const auto volume = static_cast<u8>(percentage);
Settings::values.volume.SetValue(volume);
UpdateVolumeUI();
});
volume_popup->layout()->addWidget(volume_slider);
volume_button = new VolumeButton();
@ -1078,6 +1072,12 @@ void GMainWindow::InitializeWidgets() {
volume_button->setFocusPolicy(Qt::NoFocus);
volume_button->setCheckable(true);
UpdateVolumeUI();
connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
Settings::values.audio_muted = false;
const auto volume = static_cast<u8>(percentage);
Settings::values.volume.SetValue(volume);
UpdateVolumeUI();
});
connect(volume_button, &QPushButton::clicked, this, [&] {
UpdateVolumeUI();
volume_popup->setVisible(!volume_popup->isVisible());

View file

@ -109,9 +109,13 @@ struct Values {
Settings::Specialization::Default,
true,
true};
Setting<bool> mute_when_in_background{
linkage, false, "muteWhenInBackground", Category::Audio, Settings::Specialization::Default,
true, true};
Setting<bool> mute_when_in_background{linkage,
false,
"muteWhenInBackground",
Category::UiAudio,
Settings::Specialization::Default,
true,
true};
Setting<bool> hide_mouse{
linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,
true, true};